左值参考的左值参考值与左值/右值的右值参考值

时间:2014-04-11 12:52:40

标签: c++ rvalue

左值引用的左值引用是否合法?

考虑以下示例,最终rvalueRef中的两个案例在它所引用的内容或类型(或其他内容)方面是否存在差异?

Type& ref = GetReference()
Type&& rvalueRef = std::move(ref)

vs

Type value = GetValue()
Type&& rvalueRef = std::move(value)

2 个答案:

答案 0 :(得分:3)

这两个代码都是正确的,并且在C ++中是100%合法的。仅在第一种情况下移动引用(或更好地说,如果使用适当的目标,则能够移动)的意义上存在差异,在第二种情况下,它是副本(请参阅下面的示例,澄清这个)

请注意std::move实际上并不移动对象。它只将对象转换为右值引用类型。就是这样。

另请注意,在两个情况下,rvalueRef 仍然是左值 - 具有名称(即要引用的标识符)的对象永远不会一个右值。因此,如果您实际上没有使用std::move(或使用显式强制转换)再次移动它,那么根本没有任何区别。

这是一个具体的例子:

//given function
std::string& GetReference(); 
std::string  GetValue(); 

//target function
void f(std::string param); 

您的代码如下:

std::string& ref = GetReference();
std::string&& rvalueRef = std::move(ref);

std::string value = GetValue()
std::string&& rvalueCopy = std::move(value); //named changed

直到现在根本没有差异。

但如果你这样做:

f(std::move(rvalueRef));  //actual object returned from GetReference is moved!
f(std::move(rvalueCopy)); //only a copy is moved.

在第一种情况下移动实际对象,在第二种情况下,移动副本。如果你这样做,它根本没有任何区别:

f(std::move(GetReference()));  //actual object returned from GetReference is moved!
f(std::move(GetValue()));      //only a copy is moved.

所以你看,在你的代码中,没有区别,因为根本没有实际的移动。只有演员才有。要实际移动,应该有一个适当的目标类型,可以调用move-constructor或move-assignment!在你的情况下,没有任何一个调用。

答案 1 :(得分:1)

问。 左值引用的左值引用是否合法?

这不是你要问的问题。你真正问的问题是:

问。 将右值引用转换为右值引用是否合法?

答案是肯定的。 std::move只是将其参数转换为右值引用,这始终是合法的。您正在做的事情的总体正确性取决于您对std::move结果所做的事情。您的示例代码没有任何问题。

问。 这两种情况有区别吗?

// case 1                             // case 2
Type& ref = GetReference();           Type value = GetValue();
f(std::move(ref));                    f(std::move(value));

唯一的区别是,在案例1中,ref是对GetReference()返回的对象的引用,但在案例2中,valueGetValue()返回的对象的副本。 {1}}。