删除复制/移动赋值运算符的有效签名

时间:2018-04-11 17:52:48

标签: c++ c++11 language-lawyer assignment-operator

使用以下签名删除复制或移动赋值运算符(可能是唯一的)是否有效(注意void作为结果类型)?

struct A
{
    A() = default;
    void operator = (const A &) = delete;
    void operator = (A &) = delete;
    void operator = (A &&) = delete;
};

G ++ / clang ++接受上面的代码(实际上它可以被视为缩短)。赋值运算符的签名是否有更严格的要求才能明确删除它们?

继承是否有干扰?

2 个答案:

答案 0 :(得分:2)

完全有效。如果你的班级不需要/想要/不能使用这些功能那么明确并删除它们是正确的做法(即使返回类型不参与重载决议你可能想要让它们正确只是减少混淆)。

答案 1 :(得分:2)

来自[class.copy.assign]

  

用户声明的 copy 赋值运算符X​::​operator=是类X的非静态非模板成员函数,其中只有一个X类型的参数,X&const X&volatile X&const volatile X&

,同样适用于move

  

用户声明的 move 赋值运算符X​::​operator=是类X的非静态非模板成员函数,其中只有一个X&&类型的参数,const X&&volatile X&&const volatile X&&

此处对返回类型没有限制。仅限参数类型。编译器生成returns X&的这些版本,但绝不会让您做同样的事情。

如果您仍在删除分配运算符,则返回void即可。请注意,您不需要同时删除复制和移动赋值运算符。如果删除了副本分配,则move won't be implicitly generated

  

继承是否有干扰?

没有。隐式生成的赋值运算符只是defined as deleted(并且会返回X&,尽管这是正交的)。如果你申报一个,那当然由你来做你想做的事。