问题
This is a follow-up from this Q/A.
I'm in the process of taking user Jarod42's advice by using template <template<typename> class C, typename T>
instead of the example that I have shown as my answer to the question.
My code currently looks like this:
template<template<typename> class C, typename T>
struct single_member_ops {
friend auto operator+(const C<T>& lhs, const C<T>& rhs)
{ return lhs.value + rhs.value; }
friend auto operator+(const C<T>& lhs, const T& rhs)
{ return lhs.value + rhs;}
friend auto operator+(const T& lhs, const C<T>& rhs)
{ return lhs + rhs.value;}
friend auto operator+=(const C<T> & lhs, const C<T> & rhs) {
C<T> temp;
temp.value = lhs.value + rhs.value;
return temp.value;
}
friend auto operator+=(const C<T>& lhs, const T& rhs ) {
C<T> temp;
temp.value = lhs.value + rhs;
return temp.value;
}
friend auto operator+=(const T& lhs, const C<T>& rhs) {
C<T> temp;
temp.value = lhs + rhs.value;
return temp.value;
}
};
template<typename T>
struct A : public single_member_ops<A<T>, T>{
T value;
A() = default;
explicit A(T in) : value{in} {}
explicit A(A<T>& in) : value{in.value} {}
auto& operator=(const A<T>& rhs) { return value = rhs; }
auto& operator=(const T& rhs) { return value = rhs; }
};
template<typename T>
struct B : public single_member_ops<B<T>, T> {
T value;
B() = default;
explicit B(T in) : value{in} {}
explicit B(B<T>& in) : value{in.value} {}
auto& operator=(const B<T>& rhs) {return value = rhs;}
auto& operator=(const T& rhs) { return value = rhs; }
};
int main() {
A<int> a1(4);
A<int> a2;
A<int> a3{0};
a2 = 6;
a3 = a1 + a2;
B<int> b1(5);
B<int> b2(7);
B<double> bd1(3.4);
B<double> bd2(4.5);
auto x1 = a1 + a2;
auto x2 = a1 + b2;
auto x3 = b1 + bd1;
//auto y1 = a2 - b2;
//auto y2 = b2 - a1;
A<int> z;
z += a2 + a3;
return z.value;
}
You can see it on Compiler Explorer
I'm only showing the +()
and +=()
operators to reduce the amount of code shown. I would prefer for all of my operators to be defined in this base class single_member_ops
and to be a friend to all classes that will derive from this base class.
My code example above is generating compiler errors for the lines that the pertaining operator is not defined for the defined binary operator(s):
auto x2 = a1 + b2;
auto x3 = b1 + bd1;
It appears that I'm able to use the +()
and +=()
operators just fine for all types that match in both class and its type such as in A<int>
and A<int>
which is fine. However, let's say that I want to use them interchangeably such as in the following pseudo situations:
A<int> op A<double>
A<int> op B<int>
A<int> op B<double>
What would I have to do, or what would my operators look like to achieve this? What else am I missing here?
来源:https://stackoverflow.com/questions/65993024/inheriting-from-a-template-class-set-of-operators-using-crtp