Does signature of custom assignment operator=() matter when I just want to disable it?
Asked Answered
S

3

12

I need to disable the copy assignment operator. This will work:

A& operator=(const A&);

Will it work if I don't specify exact parameters for operator=?
I mean something like this:

void operator=(void);

The returning value is right, I can write whatever I want, but what about the parameter type?
Will this override the default operator= for class?

Stodgy answered 29/5, 2016 at 8:16 Comment(3)
"will it work..."; Did you try ?Sniffle
assignment must take exactly one argument.Sabra
@WhozCraig, yes I can try and see it works or not, but I want to know why.Stodgy
O
14

From 12.8p17 of the C++ standard draft:

A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&.

I guess this replies better than any other test or sample code.

Note that something similar applies also to the move assignment operator, see 12.8p19:

A user-declared move assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X&&, const X&&, volatile X&&, or const volatile X&&.

These also confirm that, as you guessed, return value types don't matter.

Overestimate answered 29/5, 2016 at 8:32 Comment(0)
K
9

There can be different kinds of assignments. Only copy assignment and move assignment are potentially generated by the compiler. They are generated if there is no copy/move assignment. So, if you want to disable copy and/or move assignment the argument type does matter although there is some flexibility as copy assignment can different argument types. The return type doesn't matter, though.

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
};

There are also variations replacing const by volatile or const volatile qualifying as copy/move assignments. When you disable a copy assignment, automatic generation of move assignment will be disabled, too. If you disable move assignment, I think copy assignment would still be generated. If you disable anything which cannot be a copy or move assignment, copy/move assignment are still generated.

Kailey answered 29/5, 2016 at 8:34 Comment(0)
O
6

This is exact definition of an user-declared copy assignment operator from current standard (§ 12.8 p. 17):

A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&.

Notes:

  • An overloaded assignment operator must be declared to have only one parameter; see 13.5.3.
  • More than one form of copy assignment operator may be declared for a class.
  • If a class X only has a copy assignment operator with a parameter of type X&, an expression of type const X cannot be assigned to an object of type X.

Example:

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

Also, please, use delete from C++11 standard.

You can now set functions as Defaulted or Deleted.

You can now write directly that you would like to disable copying.

class A {
A(const A&) = delete;
A& operator=(const A&) = delete;    // Disallow copying
};

You can also explicitly inform compiler that you want default copy of a class. This way you can provide custom default constructor and still get default versions of other compiler-generated methods from compiler.

class B {
    B(const Y&) = default;
    B& operator=(const B&) = default;   // default copy 
};
Openfaced answered 29/5, 2016 at 8:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.