左值参考的右值参考是否合法?左值参考的左值参考值左值/右值的右值参考值
考虑下面的例子,最终的rvalueRef中的两种情况在引用或类型(或其他事物)方面是否有区别?
Type& ref = GetReference()
Type&& rvalueRef = std::move(ref)
vs
Type value = GetValue()
Type&& rvalueRef = std::move(value)
左值参考的右值参考是否合法?左值参考的左值参考值左值/右值的右值参考值
考虑下面的例子,最终的rvalueRef中的两种情况在引用或类型(或其他事物)方面是否有区别?
Type& ref = GetReference()
Type&& rvalueRef = std::move(ref)
vs
Type value = GetValue()
Type&& rvalueRef = std::move(value)
这两个代码都是正确的,在C++中是100%合法的。只有在第一种情况下引用被移动(或者更好地说,在使用适当的目的地时能够移动)并且在第二种情况下,它是副本(参见下面的示例以便解释这个)。
请注意,std::move
实际上并没有移动对象。它仅将该对象转换为右值引用类型。就是这样。
还要注意,在这两种案件,rvalueRef
是仍然左值—一个对象,它有一个名字(即一个标识符来指代)是从来没有一个rvalue。所以,如果你实际上没有使用std::move
(或使用显式投射)实际移动它,那么根本没有任何区别。
这里是一个具体的例子:
您的代码如下:
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:如果这样做,这是没有任何差别。只有演员在那里。为了实际移动,应该有一个适当的目标类型,可以调用移动构造函数或移动赋值!在你的情况下,没有任何一个的调用。
问:有一个右值引用右值引用是合法吗?
这不是你问的问题。您真正要问的问题是这样的:
问:将左值引用转换为右值引用是合法吗?
答案是肯定的。 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中,value
是由GetValue()
返回的对象的副本。