禁用移动构造函数

use*_*018 9 c++ move c++11

我想在类中禁用移动构造函数.而不是移动,我想基于复制构造函数.当我尝试编写此代码时:

class Boo
{
public:
    Boo(){}
    Boo(const Boo& boo) {};
    Boo(Boo&& boo) = delete;
};

Boo TakeBoo()
{
    Boo b;
    return b;
}
Run Code Online (Sandbox Code Playgroud)

在编译期间我收到错误:

错误C2280:'Boo :: Boo(Boo &&)':尝试引用已删除的函数

如何禁用移动构造函数并强制复制?

Mar*_*nik 19

不要创建任何移动构造函数:

class Boo
{
public:
    Boo(){}
    Boo(const Boo& boo) {};
};
Run Code Online (Sandbox Code Playgroud)

只要存在用户定义的复制构造函数,就不会自动生成移动构造函数,因此会调用复制构造函数.

  • 如果存在复制构造函数,则不会自动生成移动构造函数*.在OP的例子中就是这种情况,但是值得指出,以免读者得出结论,没有实现移动构造函数就足以避免移动.例如,一个具有两个`std :: vector`成员且没有隐式定义的复制或移动构造函数的类将获得一个自动生成的移动构造函数,用于移动向量. (6认同)

Nia*_*all 5

将功能标记为=delete会使该功能可用于重载解析,但是如果选择该功能,编译将失败;此功能不仅限于构造函数和其他特殊功能(请参见此处)。以前(大约C ++ 03)使成员成为私有成员也获得了类似的结果。

因此,如示例中的代码,实际上意味着您禁止从临时或到期值(rvalues)(移动构造函数)构造类的对象。

若要更正此问题,请完全删除move构造函数。对于该类,一旦存在副本构造函数(用户定义),则无论如何都不会隐式生成移动(移动构造函数和移动赋值运算符)。

class Boo
{
public:
    Boo(){}
    Boo(const Boo& boo) {};
    //Boo(Boo&& boo) = delete;
};
Run Code Online (Sandbox Code Playgroud)

  • 额外信息:将move构造函数标记为自己删除确实确实使其可用于重载解析;但是,如果将move-constructor隐式定义为Delete(例如,如果成员变量将其隐式或显式定义为move构造函数,则会发生这种情况),那么它*不*可用于重载解析!(超分辨率很有趣...) (2认同)