我有模板类Point2D,我需要为不同版本的模板类实现二元运算符。由于operator+
template <class T>
class Point2D
{
public:
T x;
T y;
Point2D(T _x=0,T _y=0):x(_x),y(_y)
{
}
Point2D(Point2D& ob)
{
x=ob.x;
y=ob.y;
}
template <class T1>
Point2D(Point2D<T1>& ob)
{
x=ob.x;
y=ob.y;
}
};
template <class T>
Point2D<T> operator+(const Point2D<T>& ob1,const Point2D<T>& ob2)
{
return Point2D<T>(ob1.x+ob2.x,ob1.y+ob2.y);
}
int main()
{
Point2D<int> ob1(10,10);
Point2D<double> ob2(20,20);
Point2D<double> ob3=ob2+ob1;
return 0;
}
我想启用此功能Point2D<double> ob3=ob2+ob1;
,但编译器无法推断出此运算符的正确版本
Point2D<T> operator+(const Point2D<T>& ob1,const Point2D<T>& ob2)
为了让它有效,我应该改变什么?
答案 0 :(得分:2)
使用两个模板参数:
template <class T1, class T2>
Point2D<T1> operator+(const Point2D<T1>& ob1,const Point2D<T2>& ob2)
{
return Point2D<T1>(ob1.x+ob2.x,ob1.y+ob2.y);
}
这是使编译器满意的最小变化。
但是,正如您所看到的,结果的类型使用T1
作为模板参数类型进行实例化,这可能是不可取的。因此,您需要选择最适合您工作的类型。这涉及到某种元编程。
在C ++ 11中,它非常简单,具有尾随返回类型:
template <class T1, class T2>
auto operator+(const Point2D<T1>& ob1,const Point2D<T2>& ob2) -> Point2D<decltype(obj1.x+obj2.x)>
{
typedef decltype(obj1.x+obj2.x) R;
return Point2D<R>(ob1.x+ob2.x,ob1.y+ob2.y);
}
在这里熟悉trailing-return-type:
答案 1 :(得分:1)
您需要使用两个不同的模板参数,例如:
template <typename T, typename U>
Point2D<T> operator+(const Point2D<T>& ob1, const Point2D<U>& ob2)
{
return Point2D<T>(ob1.x+ob2.x,ob1.y+ob2.y);
}
template <typename T, typename U>
Point2D<typename std::common_type<T, U>::type>
operator+(const Point2D<T>& ob1, const Point2D<U>& ob2)
{
return Point2D<typename std::common_type<T, U>::type>(
ob1.x+ob2.x,ob1.y+ob2.y
);
}