ker*_*los 6 c++ rvalue-reference move-semantics c++11
我试图通过一个简单的自制示例来掌握右值引用并移动语义,但我无法理解特定部分。我创建了以下课程:
class A {
public:
A(int a) {
cout << "Def constructor" << endl;
}
A(const A& var) {
cout << "Copy constructor" << endl;
}
A(A&& var) {
cout << "Move constructor" << endl;
}
A& operator=(const A& var) {
cout << "Copy Assignment" << endl;
return *this;
}
A& operator=(A&& var) {
cout << "Move Assignment" << endl;
return *this;
}
};
Run Code Online (Sandbox Code Playgroud)
我尝试了以下实验,看看我是否可以预测构造函数/运算符将如何被调用:
现在,我创建了一个简单的函数,它只返回一个 A 对象。
A helper() {
return A(1);
}
Run Code Online (Sandbox Code Playgroud)
现在是我不明白的部分。我创建了另一个完全没有意义的函数。它按值获取 A 对象并返回它。
A helper_alt(A a) {
return a;
}
Run Code Online (Sandbox Code Playgroud)
如果我说的有什么不对的地方,或者你觉得我可能没有理解的地方,请随时纠正我。
我的实际问题:在最后一种情况下,为什么先调用移动构造函数,然后调用移动赋值运算符,而不仅仅是移动赋值运算符?
恭喜你找到了C++的核心问题!
关于您在示例代码中看到的行为仍然有很多讨论。
有这样的建议:
A&& helper_alt(A a) {
std::cout << ".." << std::endl;
return std::move(a);
}
Run Code Online (Sandbox Code Playgroud)
这将执行您想要的操作,只需使用移动赋值,但会发出来自 g++ 的警告“警告:返回了对局部变量‘a’的引用”,即使该变量立即超出范围。
已经有其他人发现了这个问题,并且这已经成为C++ 标准语言的核心问题
有趣的是,这个问题早在 2010 年就被发现了,但直到现在才得到解决......
为了回答您的问题“在最后一种情况下,为什么先调用移动构造函数,然后调用移动赋值运算符,而不仅仅是移动赋值运算符? ”,C++ 委员会到目前为止还没有答案。准确地说,有一个提议的解决方案,并且该解决方案已被接受,但到目前为止还不是该语言的一部分。
来自:评论状态
修改第 34 段以明确将函数参数排除在复制省略之外。修改第 35 段,将函数参数纳入移动构造的资格。
| 归档时间: |
|
| 查看次数: |
1260 次 |
| 最近记录: |