Assignment operator not available in derived class

The problem is that the compiler will add an implicit assignment operator for the B class, declared as

B& operator=(const B&);

This operator will hide the operator from A, so the compiler will not know about it.

The solution is to tell the compiler to also use the operator from A with the using keyword:

class B : public A
{
public:
    using A::operator=;
};

Every class has at least one assignment operator implicitly defined when we don't provide one ourselves.

And when a member function in a derived class is defined with the same name as a member in the base class, it hides all the base class definitions for that name.

You can use a using declaration, but be warned that it will pull all the members named operator= and allow code like this:

A a;
B b;
b = a;

Which is slightly dubious.


In order to make it work, you need to bring the operator= into B's scope:

class B : public A
{
public:
using A::operator=;
};

According to the standard [class.copy.assign/8]:

Because a copy/move assignment operator is implicitly declared for a class if not declared by the user, a base class copy/move assignment operator is always hidden by the corresponding assignment operator of a derived class (16.5.3).

So, because the B::operator= has been implicitly declared, it has hidden A::operator=, which requires you to bring it into scope if you want to use it.

Further quote from the standard [over.ass/1]

An assignment operator shall be implemented by a non-static member function with exactly one parameter. Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user (15.8), a base class assignment operator is always hidden by the copy assignment operator of the derived class.

Emphasis is mine.


As pointed out by the other existing answers, the implicitly generated assignment operator of B hides the assignment operator defined in A. This is true for any non-virtual member function in a base class, the only specialty here is the automatically generated assignment operator.

But try to figure out first whether you really want to do this. Imagine your class B has data members that need to be initialized in some way. How does using the assignment from A affect these data members? A doesn't know anything of its derived class data members, they would be left untouched. Have a look at the following scenario where the assignment operator has been made available through a using directive:

class B : public A {
   public:
      using A::operator=;

      int m = 0; // Default-initialize data member to zero
};

B b;
b.m = 42;
b = 0; // Doesn't touch B::m... intended? A bug? Definitely weird.

So yes, it is possible, but error-prone and dangerous, especially when it comes to future modifications of the subclass.