error C2582: 'operator =' function is unav

2019-04-08 10:31发布

问题:

Following code gives a compilation error (at least when using MS VS 2008) for line "e=f" in main():

error C2582: 'operator =' function is unavailable in 'B'

class A {
public:
    A() { }
    static const double x;
};
const double A::x = 0.0;

class B {
public:
    B() : x(0.0) { }
    const double x;
};

int main( int argc, char *argv[] )
{
    A c,d;
    B e,f;

    c = d;
    e = f;

    return 0;
}

The default assignment operator should be generated for both classes, A and B !?

in 12.8.10: "If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly."

回答1:

The implicitly generated operator would recursively assign each non-static member. However, x is const, so it can't be assigned to. This prevents the implicit operator from being generated (specifically, it causes it to be defined as deleted).

This is specified in C++11 12.8/23:

A defaulted copy/move assignment operator for class X is defined as deleted if X has:

  • ...
  • a non-static data member of const non-class type (or array thereof), or
  • ...

(Although I just noticed that your compiler predates C++11; the rules are similar, but specified in different language, in older dialects with no concept of "deleted" functions).

If you want an assignment operator for a class whose members (or base classes) can't be reassigned, you'll have to define it yourself.

In class A, the constant member is static, so doesn't form part of an object. Therefore, it doesn't prevent an (empty) object from being assigned to.



回答2:

field 'x' is of const-qualified type of const double, the default assignment operator will be meaningless and is implicitly deleted here



回答3:

The obvious difference between class A and B is const member x beeing static vs. non-static. Assignment to a const variable is/should be impossible in any case.

The compiler obviously tries to generate the default assignment operator method for class B and silently decides to not generating one, as member x does not allow assignment.

Took me quite a long time to find out this ...

BTW: If you omit the initialization of x in class B , compiler is smart enough to find out this mistake.