mos*_*ald 16 c++ rvalue-reference c++11
我认为我对rvalue引用并不十分了解.为什么以下错误无法编译(VS2012)'foo' : cannot convert parameter 1 from 'int' to 'int &&'
?
void foo(int &&) {}
void bar(int &&x) { foo(x); };
Run Code Online (Sandbox Code Playgroud)
我会假设int &&
从bar传递到foo时将保留该类型.为什么它会int
在函数体内转换成一次?
我知道答案是使用std::forward
:
void bar(int &&x) { foo(std::forward<int>(x)); }
Run Code Online (Sandbox Code Playgroud)
所以也许我只是没有清楚地掌握原因.(另外,为什么不std::move
呢?)
Sau*_*ack 13
我总是记得左值作为一个有名字或可以解决的值.由于x具有名称,因此它将作为左值传递.引用rvalue的目的是允许函数以它认为合适的任何方式完全破坏值.如果我们在您的示例中通过引用传递x,那么我们无法知道执行此操作是否安全:
void foo(int &&) {}
void bar(int &&x) {
foo(x);
x.DoSomething(); // what could x be?
};
Run Code Online (Sandbox Code Playgroud)
这样做foo(std::move(x));
是明确地告诉编译器你已完成x并且不再需要它.如果没有这一举动,现有代码就会发生不好的事情.这std::move
是一种保障.
std::forward
用于模板中的完美转发.
Mik*_*our 11
为什么它会
int
在函数体内转换成一次?
它没有; 它仍然是对rvalue的引用.
当一个名字出现在表达式中时,它就是一个左值 - 即使它恰好是对右值的引用.如果表达式要求(即如果需要它的值),它可以转换为右值; 但它不能绑定到右值参考.
正如您所说,为了将其绑定到另一个右值引用,您必须将其显式转换为未命名的右值.std::forward
并且std::move
是方便的方法.
另外,为什么不
std::move
呢?
为什么不呢?这比std::forward
那些不知道参数是否是引用的模板更有意义.