这是本Q/A的后续内容。
我正在接受用户 Jarod42 的建议,template <template<typename> class C, typename T>
而不是使用我展示的示例作为问题的答案。
我的代码目前如下所示:
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;
}
你可以在编译器资源管理器上看到它
我只显示+()
and+=()
运算符以减少显示的代码量。我希望我的所有运算符都在这个基类中定义,single_member_ops
并成为所有从这个基类派生的类的朋友。
我上面的代码示例正在为未为定义的二元运算符定义相关运算符的行生成编译器错误:
auto x2 = a1 + b2;
auto x3 = b1 + bd1;
看来我可以很好地使用+()
and+=()
运算符来处理在类及其类型中匹配的所有类型,例如 inA<int>
和A<int>
which 很好。但是,假设我想互换使用它们,例如在以下伪情况下:
A<int> op A<double>
A<int> op B<int>
A<int> op B<double>
我必须做什么,或者我的操作员会怎样才能实现这一目标?我在这里还缺少什么?