问题描述
所以我有一个基于CRTP的矩阵类(派生类型),它需要两个模板参数template<class T,class Derived>
,并且需要重载二进制运算符+
,-
和{{1 }}乘以标量(T类)的矩阵。对于*
运算符,例如它将是
*
然后,例如使用template <class T,class Derived>
Derived operator*(const Derived &other,const T scalar)
{
Derived result = other;
for (size_t i = 0 ; i < other.get_rows(); i++)
{
for (size_t j = 0; j < other.get_cols(); j++)
{
result(i,j) *= scalar;
}
}
return result;
}
template <class T,class Derived>
Derived operator*(const T scalar,const Derived &other) { return other * scalar; }
,其中a * A
是双标量,而a
是矩阵对象(动态),编译器将无法理解要使用哪个运算符,无论类类型,因为使用的模板(A
或T
)含糊不清。
这里有人解决吗?我是否需要重载特定模板参数,例如Derived
,double
等??
解决方法
编译器可能无法识别两个重载,这两个重载都为和参数采用任意类型。在
template <class T,class Derived>
Derived operator*(const Derived &other,const T scalar) {...}
Derived
和T
只是可以用 any 类型替换的模板参数。其他操作员也是如此。两者都声明了一个operator*
,适用于任何两种类型。
如果矩阵的类型为Derived
(即某个地方有class Derived { ... };
),则可能是要使用此类型,而不要使用具有相同名称的模板参数。
template <class T>
Derived operator*(const Derived &other,const T scalar) {...}
template <class T,class Derived>
Derived operator*(const T scalar,const Derived &other) {...}
现在您有两个运算符,它们将Derived
的实例作为lhs,将任何其他类型作为rhs,反之亦然。
此外,您可以使用std::enable_if
或C++ 20 concepts & constraints模板通过std::is_integral
或std::is_floating_point
限制T
的类型,以仅允许{{1} }就是数字。
或者,如果您不能或不想对不同的矩阵子类使用运行时多态性,则可以保留初始方法(带有两个模板参数),但限制T
允许的类型使用std::is_same
的上述方法。然后SFINAE应该选择正确的过载。