双参数模板二元运算符重载
Two-parameter template ambiguous binary operator overload
所以我有一个基于 CRTP 的矩阵 class(派生类型),它采用两个模板参数 template<class T, class Derived>
,并且需要重载二元运算符 +
、-
和 *
表示矩阵乘以标量(class 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
是矩阵对象(动态),编译器将无法理解使用哪个运算符,无论class 类型,因为使用哪个模板(T
或 Derived
)不明确。
这里有人有解决方案吗? 我是否需要重载特定模板参数,例如 double
、int
等?
编译器不可能辨别两个重载,它们为两个参数采用任意类型。在
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
or C++ 20 concepts & constraints using std::is_integral
or std::is_floating_point
模板限制 T
的类型,只允许 T
的数字乘法。
或者,如果您不能或不想对矩阵的不同子类使用运行时多态性,您可以保留最初的方法(使用两个模板参数)但限制允许的类型 Dervied
上面提到的方法,使用 std::is_same
。 SFINAE 应该选择正确的重载。
所以我有一个基于 CRTP 的矩阵 class(派生类型),它采用两个模板参数 template<class T, class Derived>
,并且需要重载二元运算符 +
、-
和 *
表示矩阵乘以标量(class 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
是矩阵对象(动态),编译器将无法理解使用哪个运算符,无论class 类型,因为使用哪个模板(T
或 Derived
)不明确。
这里有人有解决方案吗? 我是否需要重载特定模板参数,例如 double
、int
等?
编译器不可能辨别两个重载,它们为两个参数采用任意类型。在
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
or C++ 20 concepts & constraints using std::is_integral
or std::is_floating_point
模板限制 T
的类型,只允许 T
的数字乘法。
或者,如果您不能或不想对矩阵的不同子类使用运行时多态性,您可以保留最初的方法(使用两个模板参数)但限制允许的类型 Dervied
上面提到的方法,使用 std::is_same
。 SFINAE 应该选择正确的重载。