Reputation: 929
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
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 B
object (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
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