And*_*Guo 5 c++ constructor c++11
引自C++ Primer
如果我们明确要求编译器通过使用生成移动操作
= default,而编译器无法移动所有成员,则移动操作将被定义为已删除如果类有一个成员定义了自己的复制构造函数但没有定义移动构造函数,或者如果类有一个成员没有定义自己的复制操作并且编译器为它定义了移动构造函数,则移动构造函数被定义为已删除无法合成移动构造函数
一些代码似乎违反了这条规则:
#include <utility>
#include <iostream>
struct X {
X() = default;
X(const X&) { std::cout << "X(const X&)" << std::endl; }
int i;
};
struct hasX {
hasX() = default;
hasX(const hasX &) = delete;
hasX(hasX &&) = default;
X mem;
};
int main()
{
hasX hx, hx2 = std::move(hx); //output is X(const X&)
}
Run Code Online (Sandbox Code Playgroud)
X 没有定义移动构造函数,编译器不能为它合成一个。
根据上面的规则,hasX删除 的移动构造函数。
但是,由于hasX删除了复制构造函数,hx2 = std::move(hx)必须调用移动构造函数来输出"X(const X&)",这说明hasX移动构造函数已定义并使用X的复制构造函数“移动”。这似乎违反了上述规则。
那么,是不是在 C++ 标准中定义或只是编译器实现?
我测试的编译器:VS2015 和 一个在线编译器
谢谢你的帮助!
你的书好像写错了。 复制是一种有效的移动操作,因此只要成员具有 形式的复制构造函数const type&,因此它可以绑定到右值,移动操作就会回退到副本。
在你的例子中
hasX(hasX &&) = default;
Run Code Online (Sandbox Code Playgroud)
可以替换为
hasX(hasX &&rhs) : mem(std::move(rhs.mem)) {}
Run Code Online (Sandbox Code Playgroud)
因为这就是默认的做法,并且它会编译得很好。
| 归档时间: |
|
| 查看次数: |
178 次 |
| 最近记录: |