Что такое использование ссылочных переменных-членов rvalue
Мне было интересно, есть ли смысл иметь ссылочную переменную rvalue (не как параметр функции)? Я понимаю использование ссылки rvalue, когда она используется как переменная функции, так как тогда можно избежать ненужных распределений и т. Д. Но есть ли переменные ссылки rvalue варианта использования, которые не являются параметрами функции? Сначала я думал, что с такими переменными мы могли бы захватывать данные, которые были переданы в качестве значения rvalue для последующего использования, но кажется, что если у нас есть ссылочная переменная rvalue, то мы уже можем взять ее адрес, и поэтому она больше не может быть ссылкой на rvalue.
Я попробовал следующий код, и он (неудивительно) не компилируется. Так зачем мне вообще иметь ссылочную переменную rvalue?
void test(int&& a) {}
int&& a(22);
test(a);
Спасибо!
1 ответ
Ваш a
Вот имя ссылки на Rvalue. a
сам по себе является lvalue (вы можете взять его адрес) типа rvalue reference (да, немного сбивает с толку). Поэтому, когда вы передаете a
в test(a)
Вы передаете lvalue. Думайте о lvalues как о любом объекте, у которого есть имя, или из которого вы можете взять его адрес. И вы не можете привязать lvalue к ссылке на rvalue, следовательно, ошибка компиляции
ошибка: не может привязать значение int к значению int&&
Вам нужно пройти std::move(a)
, В этом случае вы отбрасываете значение a
,
Обратите внимание, что внутри вашей функции a
также является lvalue (опять же, вы можете выполнять над ним операции lvalue, такие как получение его адреса и т. д.). Вам нужен актерский состав (std::move
) каждый раз, когда вы хотите использовать его в качестве значения. Например, скажем, у вас есть объект Bar
с переменной-членом Foo member;
и вы хотите перейти в него с помощью функции-члена f
:
void Bar::f(Foo&& param)
{
member = std::move(param); // need std::move here to move param into member
}
// invoked it as
bar.f(std::move(some_foo)); // move some_foo into param
Если вы не используете param
к значению ссылки с std::move
тогда ты не двигаешься param
в member
копируй (если param
возможность копирования, в противном случае вы получите ошибку во время компиляции), так как param
само по себе является lvalue. Надеюсь, это проясняет это.