如果我默认复制构造函数,是否会生成构造函数和移动赋值?

时间:2014-01-18 21:46:54

标签: c++ move-semantics default-constructor

我对如何最好地定义可复制但不可移动的类感到困惑。在我看来,删除移动构造函数是一个坏主意,因为那时我无法从临时构造。另一方面,我不希望编译器为我隐式生成一个可能错误或可能导致意外行为的移动构造函数。我的问题是是否允许编译器隐式生成以下类的移动构造函数:

class C {
    public:
    int i_;
    C(const C&) = default;
}

3 个答案:

答案 0 :(得分:4)

CWG 1402之后

[class.copy] / 9:

  

如果类X的定义未明确声明移动构造函数,则当且仅当

时,将隐式声明一个默认值。      
      
  • X没有用户声明的复制构造函数,
  •   
  • X没有用户声明的副本分配运算符
  •   
  • X没有用户声明的移动赋值运算符和
  •   
  • X没有用户声明的析构函数。
  •   

答案 1 :(得分:2)

  

如果类X的定义没有明确声明一个移动构造函数,当且仅当

时,才会隐式声明一个默认值。      
      
  • X没有用户声明的复制构造函数
  •   
  • [和......]
  •   

由于复制构造函数是用户声明的(即使它是默认的,这意味着它不是用户提供的),因此移动构造函数不会被隐式声明为默认值。

你是对的,如果你明确地delete移动构造函数,你将无法从临时构造中构造,因为删除的移动构造函数将由重载决策选择。因此,您用于可复制但不可移动的类的方法是正确的。

答案 2 :(得分:0)

相对于您的示例,编译器将隐式声明移动构造函数,因为复制构造函数的第一个声明是默认定义。在这种情况下,复制构造函数被视为隐式定义。但是,如果您要按以下方式更改类定义

class C {
    public:
    int i_;
    C(const C&);
};

C::C( const C & ) = default;

然后在这种情况下,编译器不会生成移动构造函数,因为用户显式声明了复制构造函数。