class MyClass {
public:
MyClass()
{
std::cout << "default constructor\n";
}
MyClass(MyClass& a)
{
std::cout << "copy constructor\n";
}
MyClass(MyClass&& b)
{
std::cout << "move constructor\n";
}
};
void test(MyClass&& temp)
{
MyClass a(MyClass{}); // calls MOVE constructor as expected
MyClass b(temp); // calls COPY constructor... not expected...?
}
int main()
{
test(MyClass{});
return 0;
}
对于上面的代码中,我预期无论在测试对象创建()来调用移动的构造,因为b是右值引用类型(MyClass的& &)。c + +移动的构造不要求右值参考
但是,将b传递给MyClasss构造函数并不像预期的那样调用移动构造函数,而是调用复制构造函数。
为什么第二个案例调用拷贝构造函数,即使传入的参数是MyClass类型& &(r值参考)???
我使用的是gcc 5.2.1。要重现我的结果,您必须将-fno-elide-constructors选项传递给gcc以禁用副本优化。
void test(MyClass&& temp)
{
if (std::is_rvalue_reference<decltype(temp)>::value)
std::cout << "temp is rvalue reference!!\n";
else
std::cout << "temp is NOT rvalue!!\n";
}
上面的代码打印出“温度是右值引用”,即使温度而得名。
temp的类型是右值引用类型。
表达'temp'计算结果为左值refernce,而不是右值引用。你将'temp'声明为右值引用并不重要。一个*名为*的引用永远是一个左值。 – AnT
@AnT你在C++标准文档中有任何参考吗?我非常努力地寻找这条规则的任何参考,但我找不到一个...... – SHH
请参阅** 5表达式**的开头。全部在5/5,5/6和5/7。特别参见注5/7,它基本上是这样描述的。此外,链接的“重复”链接到一个托马斯贝克尔关于这个话题的文章。 – AnT