Путаница между "rvalue" и "rvalue reference" в книге - PullRequest
2 голосов
/ 08 мая 2020

(Я искал [c ++] книгу «Функциональное программирование на c ++» , которая дает только 4 нерелевантных результата.)

Я читаю Функциональное программирование на C ++ от Ивана Чукича , а на странице 118 есть предложение, которое я не уверен, что понял. Раздел посвящен перегрузкам rvalue и lvalue функций-членов, и предложение выглядит следующим образом, где вторая перегрузка - это та, которая использует квалификатор ссылочного типа &&:

Вторая перегрузка будет вызвана для объектов, из которых вам разрешено использовать данные - временные объекты и другое rvalue ссылки .

Мои сомнения вот эти:

  • часть в itali c меня в первую очередь озадачивает, как в что еще это могло быть, если не временное?, но, возможно, это просто потому, что у меня до сих пор нет четкого представления о том, что такое xvalues;
  • слово, выделенное жирным шрифтом , действительно меня озадачивает, поскольку предложение кажется значимым только мне если я удалю это слово.

Код ниже предназначен для подтверждения моего понимания.

В самом деле, я понимаю, что если я скажу rvalue ссылка , я про параметр функции (так у него есть имя; пример: a в объявлении бесплатной функции f), объявленный как ссылка rvalue на фактический аргумент, или переменная, которую я объявил (так что у нее есть имя; пример: rr) как ссылка rvalue на другая переменная; (fwiw, оба объекта referen c - ed должны быть rvalue, иначе ссылка не будет привязана). В любом случае, поскольку у него есть имя, вызов на нем функции-члена f приведет к вызову перегрузки lvalue, не так ли?

Так есть ли неправильная формулировка в книге, или я что-то не хватает?

#include <iostream>

struct A {
  void f() &  { std::cout << "lvalue\n"; } // const & in the book, but it shouldn't make any difference
  void f() && { std::cout << "rvalue\n"; }
};

void f(A&& a) { a.f(); } // a is an lvalue (of type rvalue ref to)

int main() {
  A a;          // "normal" object
  A&& rr = A{}; // rvalue reference to a temporary (with life extended)

  a.f();
  A{}.f(); // only here I expect the rvalue overload to be called, and this is the case
  f(A{});
  rr.f();
}

1 Ответ

1 голос
/ 08 мая 2020

слово, выделенное жирным шрифтом , действительно меня озадачивает, поскольку предложение кажется мне значимым только в том случае, если я удаляю это слово.

Я согласен. IMO, чтобы быть более точным, предложение должно быть

Вторая перегрузка будет вызываться для объектов, из которых вам разрешено использовать данные - rvalues ​​(prvalues ​​или xvalues).

Ссылка на Rvalue используется для типов, rvalue используется для категорий значений , они независимые вещи. В этом случае, какая перегрузка будет вызвана, зависит от категории значения, т.е. вызываемый объект - это lvalue или rvalue, которые не имеют ничего общего с его типом.

часть в itali c меня в первую очередь озадачивает, как и в , что еще это может быть, если не временное ? что такое xvalues;

Да, xvalues ​​также являются rvalues. Учитывая, что int x = 0; std::move(x) - это значение x, но не временное.

...