我正在尝试构建一个模板化的向量类,它可以基于任何算术类型并使用它们进行数学运算。因此,应该允许Vec 3+ Vec 3。以下是我的声明:
template <typename T>
class Vec3 {
private:
T _x, _y, _z;
public:
static_assert(std::is_arithmetic_v<T>, "Type must be arithmetic");
Vec3(T x, T y, T z);
~Vec3() = default;
template <typename U, typename V>
friend Vec3<T> operator+(Vec3<U> lhs, const Vec3<V>& rhs);
};
我为这个函数写了两个定义(相同的hpp文件,但更进一步),一个是如果所有输入类型都相同,那么输出类型也应该相同,但如果其中一个不同,那么输出取决于:int+double-〉double,double+int -〉double,long+int -〉long,...你懂的。
template <typename T>
Vec3<T> operator+(Vec3<T> lhs, const Vec3<T>& rhs) {
return Vec3<T>(T x, T y, T z);
}
template <>
Vec3<double> operator+(Vec3<int> lhs, const Vec3<double>& rhs) {
return Vec3<double>(double x, double y, double z);
}
template <>
Vec3<double> operator+(Vec3<double> lhs, const Vec3<int>& rhs) {
return Vec3<double>(double x, double y, double z);
}
...
我以为我会为所有允许类型的组合重载运算符+,但是我得到了一个错误:
error: template-id 'operator+><' for 'Color3<double> operator+(Color3<int>, const Color3<double>&)' does not match any template declaration
什么是正确的方法去设置任何数量的类型的可能组合?谢谢。
2条答案
按热度按时间afdcj2ne1#
如果你想让任何两个基于
Vec3
的实体都能使用operator+
,你可以添加一个friend
来推导正确的返回类型:Vec3<decltype(U{} + V{})>
:b4lqfgs42#
这并不是对所提问题的直接回答,而是演示了如果将数据组织成与范围兼容的形式,编写起来有多容易:
Compiler Explorer link.
如果需要,可以添加类型约束,但是
vsum(std::plus{}, ...)
会自动为任何具有合适operator+
的对象工作。我把它改成变元的,因为为了快速演示,它实际上可以减少输入,但是将它固定为两个范围参数是没有问题的,显然它也可以毫不费力地推广到任意维数。