Hrant Nurijanyan
Hrant Nurijanyan

Reputation: 929

C++ inheritance and assignment operator

I am using CRTP to implement a C++ feature.

Now I've faced a situation like this.

template<typename T>
struct A {
    char a;

    T operator+(const T& other){
        T t;
        t.a = a + other.a;
        return t;
    }
};

struct B : A<B>{

};

struct C : B {
    C& operator=(const C& other){
        a = other.a;
        return *this;
    }
};

int main() {
    C c1,c2,c3;
    c3 = c1 + c2;
    return 0;
}

This code does not compile saying no viable overloaded=

How can I resolve the issue without adding any code to struct A and struct B?

Upvotes: 2

Views: 191

Answers (2)

Pat. ANDRIA
Pat. ANDRIA

Reputation: 2412

You also have the possibility to overload the operator+ for the C class to allow the c1 + c2 code to return a C object instead of a Bobject (as it currently does due to the operator+ defined in the B class). In this way, you obtain a C object as a result of c1+c2 that may be assigned using the defined operator= in class C.

For instance, add this function to the C class like the following:

C& operator+(const C& other){
        // for example add the two operands' characters
        this->a += other.a;
        return *this;
    }

Beware though of the idea behind your choice as it may compile but not do what you would like it to do.

Overloading + or = may depend on what you would like to do with your code and the type you would like to obtain from the operation c1+c2.

Upvotes: 1

RoQuOTriX
RoQuOTriX

Reputation: 3001

You need to create the assign operator which takes B as reference:

struct C : B {
    C& operator=(const C& other){
        return *this = static_cast<const B&>(other);
    }

    C& operator=(const B& other){
        a = other.a;
        return *this;
    }
};

Short explanation why you need this (I hope I am not wrong):

The + operator returns a B reference as B is the template parameter, not C. So ignoring the + there would be an assignment C = B which is not possible. To be clear, you would not need your first assignment operator to run your code.

Maybe also this is clearer and better:

struct C : B {
    B& operator=(const B& other){
        a = other.a;
        return *this;
    }
};

Now your assignment operator takes B as input and output.

Upvotes: 3

Related Questions