Что такое использование ссылочных переменных-членов 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. Надеюсь, это проясняет это.

Другие вопросы по тегам