当我只想禁用它时,自定义赋值运算符=()的签名是否重要?

use*_*289 11 c++ operator-overloading assignment-operator

我需要禁用复制赋值运算符.这将有效:

A& operator=(const A&);
Run Code Online (Sandbox Code Playgroud)

如果我没有指定确切的参数,它会工作operator=吗?
我的意思是这样的:

void operator=(void);
Run Code Online (Sandbox Code Playgroud)

返回值是正确的,我可以写任何我想要的,但参数类型怎么样?
这会覆盖operator=类的默认值吗?

sky*_*ack 13

12.8p17的C++标准草案:

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

我想这比任何其他测试或示例代码都要好.

请注意,类似的东西也适用于移动赋值运算符,请参见12.8p19:

甲用户声明的移动赋值运算符X ::运算符=是类X的X型的正好一个参数&&,常量X &&,易失性X &&或const volatile X &&非静态非模板的成员函数.

这些也证实,正如您所猜测的那样,返回值类型并不重要.


Die*_*ühl 8

可以有不同类型的作业.只有拷贝赋值移动作业都可能由编译器生成.如果没有复制/移动分配,则生成它们.因此,如果要禁用复制和/或移动赋值,则参数类型确实很重要,尽管存在一些灵活性,因为复制赋值可以使用不同的参数类型.但是返回类型并不重要.

class A {
public:
    void operator=() = delete; // not legal: assignment takes exactly one argument
    void operator=(A) = delete; // OK: copy assignment disabled
    void operator=(A&) = delete; // OK: copy assignment disabled
    void operator=(A const&) = delete; // OK: copy assignment disabled
    void operator=(A&&) = delete; // OK: move assignment disabled
};
Run Code Online (Sandbox Code Playgroud)

也有变化更换constvolatileconst volatile资格作为复制/移动分配.禁用复制分配时,也将禁用自动生成移动分配.如果禁用移动分配,我认为仍会生成复制分配.如果禁用任何不能复制或移动分配的内容,仍会生成复制/移动分配.


Loo*_*pes 5

这是来自当前标准的用户声明的复制赋值运算符的精确定义(第12.8页,第17页):

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

笔记:

  • 必须将重载赋值运算符声明为只有一个参数; 见13.5.3.
  • 可以为类声明多种形式的复制赋值运算符.
  • 如果类X只有一个带有类型X&参数的复制赋值运算符,则不能将类型为const X的表达式赋给类型为X的对象.

例:

struct X {
X();
X& operator=(X&);
};
const X cx;
X x;
void f() {
x = cx; // error: X::operator=(X&) cannot assign cx into x
}
Run Code Online (Sandbox Code Playgroud)

另外,请使用C++ 11标准中的删除.

您现在可以将功能设置为默认或已删除.

您现在可以直接写入要禁用复制的内容.

class A {
A(const A&) = delete;
A& operator=(const A&) = delete;    // Disallow copying
};
Run Code Online (Sandbox Code Playgroud)

您还可以显式通知编译器您需要类的默认副本.这样,您可以提供自定义默认构造函数,并仍然可以从编译器获取其他编译器生成的方法的默认版本.

class B {
    B(const Y&) = default;
    B& operator=(const B&) = default;   // default copy 
};
Run Code Online (Sandbox Code Playgroud)