Mik*_*ney 3 c++ move move-semantics c++11
我正在尝试理解“Effective Modern C++”中有关特殊成员函数生成的第 17 条,因此我尝试了一些示例并尝试推理某些行为。书中写道:
\n\n\n\n\n..当我提到移动操作移动构造或移动分配数据成员或基类时,不能保证移动实际上会发生。\xe2\x80\x9c成员移动\xe2\x80\x9d 实际上更像是成员移动请求,因为\xe2\x80\x99t 移动启用的类型(即不为移动操作提供特殊支持,例如,大多数 C++98 遗留类)将通过其复制操作\xe2\x80\x9cmoved\xe2\x80\x9d。\n ...\n 此外,不会为任何生成\xe2\x80\x99d 移动操作显式声明复制操作的类。
\n
如果我显式删除移动构造函数,则下面的代码会出错,但如果我不这样做,则对象“s1”将被复制构造而不会出现任何错误。这是指向相同代码的 wandbox 链接:wandbox link。我想我不明白删除移动构造函数和不定义移动构造函数之间的区别。
\n\n#include <iostream>\n\nstruct S\n{\n S() = default;\n S(const S&) {\n std::cout << "Copying" << std::endl;\n }\n // S(S&&) = delete;\n};\n\nS return_lvalue() {\n S ret{};\n return ret;\n}\n\nint main() {\n std::cout << "Hello world" << std::endl;\n // Error here if I delete move constructor\n S s1 = return_lvalue();\n}\nRun Code Online (Sandbox Code Playgroud)\n
我想我不明白删除移动构造函数和不定义移动构造函数之间的区别。
当你这样做时
struct S
{
S() = default;
S(const S&) {
std::cout << "Copying" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
编译器不会生成移动构造函数。如果您尝试移动它,重载解析只会找到S(const S&)并且您将获得一个副本。和
struct S
{
S() = default;
S(const S&) {
std::cout << "Copying" << std::endl;
}
S(S&&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
当您移动 类型的对象时S,重载解析会找到S(const S&)和 ,S(S&&)但它会选择 ,S(S&&)因为它是更好的匹配。然后它发现它已被删除并且您收到错误。
您需要记住的是删除的构造函数不会将它们从类中删除。它声明它们并使它们可用于重载决议,并且只有在重载决议发生后,它才会检查它们是否被删除。
| 归档时间: |
|
| 查看次数: |
558 次 |
| 最近记录: |