双参数模板二元运算符重载

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 类型,因为使用哪个模板(TDerived)不明确。

这里有人有解决方案吗? 我是否需要重载特定模板参数,例如 doubleint 等?

编译器不可能辨别两个重载,它们为两个参数采用任意类型。在

template <class T, class Derived>
Derived operator*(const Derived &other, const T scalar)  {...}

DerivedT 只是模板参数,可以用 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 应该选择正确的重载。