Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

operator= and functions that are not inherited in C++?

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...

  1. What is the reason of that ?
  2. Is there any workaround to inherit the assignment operator ?
  3. Is it also the case for operator+=, operator-=, ... ?
  4. Are all other functions (apart from constructors/operator=) inherited ?

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; } 
like image 403
Vincent Avatar asked Aug 17 '12 16:08

Vincent


People also ask

Which functions are not inherited?

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.

Which operator is not inherited by derived class?

No operator= can be declared as a nonmember function. It is not inherited by derived classes.

Are operators inherited?

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 inheritance?

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.


2 Answers

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);     } }; 
like image 136
eq- Avatar answered Sep 18 '22 05:09

eq-


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.)

like image 24
James Kanze Avatar answered Sep 21 '22 05:09

James Kanze