Until a test I've just made, I believed that only Constructors were not inherited in C++. But apparently, the assignment operator=
is not too...
operator+=
, operator-=
, ... ? In fact, I encountered this problem as I was doing some CRTP :
template<class Crtp> class Base { inline Crtp& operator=(const Base<Crtp>& rhs) {/*SOMETHING*/; return static_cast<Crtp&>(*this);} }; class Derived1 : public Base<Derived1> { }; class Derived2 : public Base<Derived2> { };
Is there any solution to get that working ?
EDIT : OK, I have isolated the problem. Why the following isn't working ? How to solve the problem ?
#include <iostream> #include <type_traits> // Base class template<template<typename, unsigned int> class CRTP, typename T, unsigned int N> class Base { // Cast to base public: inline Base<CRTP, T, N>& operator()() { return *this; } // Operator = public: template<typename T0, class = typename std::enable_if<std::is_convertible<T0, T>::value>::type> inline CRTP<T, N>& operator=(const T0& rhs) { for (unsigned int i = 0; i < N; ++i) { _data[i] = rhs; } return static_cast<CRTP<T, N>&>(*this); } // Data members protected: T _data[N]; }; // Derived class template<typename T, unsigned int N> class Derived : public Base<Derived, T, N> { }; // Main int main() { Derived<double, 3> x; x() = 3; // <- This is OK x = 3; // <- error: no match for 'operator=' in ' x=3 ' return 0; }
reason constructors aren't inherited Inheritance means a derived object can use a base-class method, but, in the case of constructors, the object doesn't exist until after the constructor has done its work.
No operator= can be declared as a nonmember function. It is not inherited by derived classes.
All overloaded operators except assignment (operator=) are inherited by derived classes. The first argument for member-function overloaded operators is always of the class type of the object for which the operator is invoked (the class in which the operator is declared, or a class derived from that class).
Which operator is used for inheriting a class in C++? A colon ( : ) is used to inherit from another class, usually in combination with an access specifier, typically public.
The assignment operator is technically inherited; however, it is always hidden by an explicitly or implicitly defined assignment operator for the derived class (see comments below).
(13.5.3 Assignment) 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 a class if not declared by the user, a base class assignment operator is always hidden by the copy assignment operator of the derived class.
You can implement a dummy assignment operator which simply forwards the call to the base class operator=
, like this:
// Derived class template<typename T, unsigned int N> class Derived : public Base<Derived, T, N> { public: template<typename T0, class = typename std::enable_if<std::is_convertible<T0, T>::value>::type> inline Derived& operator=(const T0& rhs) { return Base<Derived, T, N>::operator=(rhs); } };
The assignment operator is inherited, sort of, but... In any given class, if you do not provide a copy assignment operator, the compiler generates one for you. That means that your derived classes effectively have an assignment operator:
Derived& operator=( Derived const& );
And the usual hiding rules apply; this hides all of the base class assignment operators. (If the base class had an assignment operator with this signature, the derived class would inherit it normally.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With