右值引用成员变量有啥用

Posted

技术标签:

【中文标题】右值引用成员变量有啥用【英文标题】:What is the use of rvalue reference member variables右值引用成员变量有什么用 【发布时间】:2015-05-17 19:40:01 【问题描述】:

我想知道有一个右值引用变量(不是作为函数参数)是否有意义?我理解在将右值引用用作函数变量时使用它,因为这样可以避免不必要的分配等。但是是否存在不是函数参数的用例右值引用变量?最初我认为使用这些变量我们可以捕获作为右值传入的数据以供以后使用,但似乎如果我们有一个右值引用变量,那么我们已经可以获取它的地址,因此它不能再是右值引用了。

我尝试了以下代码,但它(不出所料)无法编译。那么为什么我会想要一个右值引用变量呢?

void test(int&& a) 

int&& a(22);
test(a);

谢谢!

【问题讨论】:

如果你std::move(a),它会编译。 【参考方案1】:

您的a 是右值引用的名称。 a 本身是一个右值引用类型的左值(你可以获取它的地址)(是的,有点混乱)。因此,每当您将a 传递给test(a) 时,您都会传递一个左值。将左值视为具有名称的任何对象,或者您可以稍后获取其地址。而且您不能将左值绑定到右值引用,因此会出现编译错误

错误:无法将 'int' 左值绑定到 'int&&'

您需要传递std::move(a)。在这种情况下,你抛弃了a 的左值性。

请注意,在您的函数内部 a 也是一个左值(同样,您可以对其执行左值操作,例如获取其地址等)。任何时候你都需要一个演员 (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 本身就是一个左值。希望这可以澄清它。

【讨论】:

好的,这是否意味着,我实际上确实用我的变量“a”捕获了一些右值引用——int&& 的类型表明了这一点,但是为了将它用作实际的右值引用,我有通过手动丢弃左值来做一些额外的工作,这是安全的,因为我已经知道它是右值引用,只是存储在左值变量中? @bim_bam 是的,完全正确。而“工作”只是在程序员方面,编译器以零开销执行强制转换。 @bim_bam 我不得不说,我不知道在函数参数之外使用右值引用的任何好的例子,尽管可能有人可以提出一个例子。 '你不能将左值绑定到右值引用'是问题的简短回答 当您不再将对象视为左值或右值时会更清楚;具有值类别的是 表达式,而不是它们命名(或未命名)的事物。

以上是关于右值引用成员变量有啥用的主要内容,如果未能解决你的问题,请参考以下文章

深入思考右值引用

无法在成员函数中绑定右值引用参数

c++11:左值右值

重新理解C11的右值引用

C11新特性右值引用&&

静态转换为右值引用和 std::move 之间有啥区别吗