Many, many, many posts about inheriting operator=, with the usual answer being "it's overshadowed by the implicitly defined one, use using Base::operator= if you know what you're doing".
Here's a hopefully slightly different question. Consider the following in which base class A knows about the exact type of the derived class:
#include <iostream>
template <typename E>
struct A {
E& operator= (const E& other) {
std::cout << "A<E>::op=\n";
return *(E*)this;
}
E& operator= (E& other) {
std::cout << "A<E>::op no const=\n";
return *(E*)this;
}
};
struct B : public A<B> {
using A<B>::operator=;
};
int main () {
B x, y;
x = y;
const B z;
x = z;
}
In the main function, when calling x = y, the method E& A<E>::operator= (E& other) with E = B is called, as expected. However, x = z does not call E& A<E>::operator= (const E& other).
Why? (Note that this is a question about behavior, not style :-) )
Why?
Because x = z uses the implicitly defined
B& B::operator=(const B&)
and the implicitly defined
A& A::operator=(const A&)
// instantiated as:
A<B>& A<B>::operator=(const A<B>&)
The implicit definitions are not removed just because you bring the base class operators out of hiding. See [class.copy]/24:
A using-declaration ([namespace.udecl]) that brings in from a base class an assignment operator with a parameter type that could be that of a copy/move assignment operator for the derived class is not considered an explicit declaration of such an operator and does not suppress the implicit declaration of the derived class operator; the operator introduced by the using-declaration is hidden by the implicitly-declared operator in the derived class.
The reason why the other case, x = y, instead uses E& A::operator= (E& other) is because it's a better match since it doesn't need to convert y to a const&.