用于删除复制/移动分配运算符的有效签名

Valid signature to delete copy/move assignment operator

本文关键字:有效 运算符 分配 删除 复制 移动 用于      更新时间:2023-10-16

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

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

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

继承的情况下是否有任何干扰?

来自 [class.copy.assign]:

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

同样,对于移动:

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

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

如果仍然要删除分配运算符,则返回void就可以了。请注意,您不需要同时删除复制和移动分配运算符。如果删除复制分配,则不会隐式生成移动。

继承

的情况下是否有任何干扰?

不。隐式生成的赋值运算符将被定义为已删除(并将返回X&,尽管这是正交的)。如果你声明一个,那么这当然取决于你做任何你想做的事。

这是完全有效的。如果你的类不需要/想要/不能使用这些函数,那么显式并删除它们是正确的做法(即使返回类型不参与重载解析,你可能希望让它们正确只是为了减少混淆)。