C++ 删除移动构造函数时,为什么不复制我的对象?
我试图用这段代码来演示复制构造函数的使用。我的假设是,当我有一个按值返回的函数时,默认情况下,我的编译器将执行对象的移动。但是当move构造函数不可用时,编译器将进行复制(在C++03中,编译器将在按值返回时进行复制)。那么,为什么在下面的示例中,编译器尝试调用显式删除的move构造函数而不是可用的copy构造函数呢?我在GCC4.7.2中编译这个C++ 删除移动构造函数时,为什么不复制我的对象?,c++,c++11,C++,C++11,我试图用这段代码来演示复制构造函数的使用。我的假设是,当我有一个按值返回的函数时,默认情况下,我的编译器将执行对象的移动。但是当move构造函数不可用时,编译器将进行复制(在C++03中,编译器将在按值返回时进行复制)。那么,为什么在下面的示例中,编译器尝试调用显式删除的move构造函数而不是可用的copy构造函数呢?我在GCC4.7.2中编译这个 struct S { S() = default; S(S const &) = default; S(S&
struct S
{
S() = default;
S(S const &) = default;
S(S&&) = delete;
};
S f() { return S{}; }
int main()
{
f();
}
prog.cpp:在函数的f()中
:程序cpp:8:18:错误:使用已删除的函数
'S::S(S&&)
程序cpp:5:5:错误:在此处声明
删除的移动成员是邪恶的。它们不是非法的,因为总有一天,有人会发现它们的巧妙用途。但我还没看到它有什么用处 删除特殊成员与没有特殊成员不是一回事。这一点在move构造函数和move赋值运算符中最为明显 存在时,无论是删除的、默认的还是用户定义的,移动构造函数和移动分配操作符都参与重载解析。这意味着他们与特殊副本成员“竞争”。复制成员通常倾向于常量左值,而移动成员则吸引右值 从函数返回局部类型时(当局部类型与返回类型是同一个非cv限定类型时),return语句首先将返回表达式视为右值,只有当它找不到合适的构造函数时,才会将其视为左值。即,匹配适当的构造函数以从函数返回本地对象是一个两阶段操作 如果您根本没有move构造函数(甚至没有删除),但是您有一个普通的copy构造函数(采用常量&),那么return语句中的rvalue将与copy构造函数匹配 当您有一个移动构造函数时,即使它被标记为deleted,return语句中的右值也会发现移动构造函数比复制构造函数更匹配 摘要 除非你真的知道自己在做什么,永远不要删除移动成员。如果您不希望您的类型是可移动的,只需不定义移动成员并确保您声明了复制成员,即使复制成员是
=default
'd
更新
我想很难引用标准中删除的内容 不行吗?——DyP 8.4.3删除的定义[dcl.fct.def.delete] 2隐式引用已删除函数的程序,或 明确地说,除了声明它,它是格式错误的。[注:此 包括隐式或显式调用函数并形成 指向函数成员的指针或指针。它甚至适用于 表达式中可能未计算的引用。如果 函数重载,仅当函数为 通过过载分辨率选择。-结束注释] 更新2 12.8复制和移动类对象[class.copy] 9如果类X的定义没有显式声明移动 构造函数,则仅当且仅当 如果
- X没有用户声明的复制构造函数
- X没有用户声明的复制分配运算符
- X没有用户声明的移动分配运算符,并且
- X没有用户声明的析构函数
删除的移动成员是邪恶的。它们不是非法的,因为总有一天,有人会发现它们的巧妙用途。但我还没看到它有什么用处 删除特殊成员与没有特殊成员不是一回事。这一点在move构造函数和move赋值运算符中最为明显 存在时,无论是删除的、默认的还是用户定义的,移动构造函数和移动分配操作符都参与重载解析。这意味着他们与特殊副本成员“竞争”。复制成员通常倾向于常量左值,而移动成员则吸引右值 从函数返回局部类型时(当局部类型与返回类型是同一个非cv限定类型时),return语句首先将返回表达式视为右值,只有当它找不到合适的构造函数时,才会将其视为左值。即,匹配适当的构造函数以从函数返回本地对象是一个两阶段操作 如果您根本没有move构造函数(甚至没有删除),但是您有一个普通的copy构造函数(采用常量&),那么return语句中的rvalue将与copy构造函数匹配 当您有一个移动构造函数时,即使它被标记为deleted,return语句中的右值也会发现移动构造函数比复制构造函数更匹配 摘要 除非你真的知道自己在做什么,永远不要删除移动成员。如果您不希望您的类型是可移动的,只需不定义移动成员并确保您声明了复制成员,即使复制成员是
=default
'd
更新
我想很难引用标准中删除的内容 不行吗?——DyP 8.4.3删除的定义[dcl.fct.def.delete] 2隐式引用已删除函数的程序,或 明确地说,除了声明它,它是不可能的