c++ - Matrix 中没有 'operator *' 的匹配运算符

标签 c++ templates casting operators

我有一个如下所示的矩阵类:

template <size_t M, size_t N, typename T>
class Matrix
{
public:
    Matrix<M, N, T> operator +(const Matrix<M, N, T>& B) const;
    template <size_t P> Matrix<M,P,T> operator*(const Matrix<N, P, T>& B) const;
    template <typename T2> operator T2() const;  

private:
  T data[M][N];
};

// ... the body is in header file too  ...//

正文写的很好,一切正常。 当我如下定义两个矩阵时:

Matrix < 10, 10, int> m1;
Matrix < 10, 10, float> m2;

m1 + m2;  // OK
m1 * m2;  // error: no match for 'operator*' in 'm1 * m2'

第一个“+”运算符运行良好,因为对其执行了隐式转换。 但是对于不同值类型的第二个 '*' 运算符,会发生错误。

error: no match for 'operator*' in 'm1 * m2'

有什么想法吗?!

更新: 所有代码都在头文件中。除了“*”运算符,我没问题。

关于“+”运算符,您能说些什么?我知道关于模板/运算符/转换的一切......但是这个问题就像我的 gcc 编译器的错误!?我写了一个转换运算符,这个运算符在“+”运算符之前调用,但我不知道为什么它不执行“*”运算符!

最佳答案

这个问题或多或少是经典的。重载决议开始于 建立一个可能的功能列表;在这种情况下,函数名为 operator* .为此,它添加所有 operator*其中的功能 列表的作用域,并尝试通过以下方式实例化所有函数模板 应用类型扣除;如果类型推导成功,它会添加 将模板实例化到列表中。 (函数模板是 不是函数。函数模板的实例化是 功能。)

模板类型推导的规则与使用的规则不同 过载决议。特别是,只有非常小的一组 转换被考虑。用户定义的转换运算符不是 经过考虑的。结果是在m1 * m2 , 类型推导为 operator*失败(因为它需要一个不是 经过考虑的)。所以没有添加函数模板的实例化 列表,没有其他operator* .

更一般地说:你是operator T2()不允许类型推导 即使它被允许;有无数次转换 这将匹配 operator* .我怀疑,事实上,你做到了 太笼统;你想要一个 operator Matrix<M, N, T2>() . (不是那个 这在这里会有所帮助,但在某些情况下它可能会消除 歧义。)

您可以通过定义一个来使其工作:

template<size_t P, tyepname OtherT>
Matrix<M, P, T> operator*( Matrix<N, P, T> const& rhs ) const;

,然后在 operator* 内部进行转换。 (我没试过, 我不确定,但我认为你现有的 operator*应该 被认为“更专业”,因此在类型时被选择 两者都推演成功。)

话虽如此,我认为您的做法是错误的。 你真的想要 m1 * m2 的返回类型吗?和 m2 * m1成为 不同的。对于初学者,我需要客户端代码来制作 显式转换(您当前的代码就是这种情况);如果你这样做 想要支持隐式转换,我认为你需要做 operator*一个全局的,使用某种简单的元编程来 确定正确的返回类型(即给定矩阵 longunsigned ,您可能希望返回类型为 unsigned long , 因为这是这些类型的混合类型算术给出的结果 否则),将两边都转换为目标类型,然后进行算术运算 在上面。很多工作可能不是很重要或 有用的功能。 (当然,只是我的意见。如果你的客户真的 想要混合类型算法,并愿意为此付出代价……)

关于c++ - Matrix 中没有 'operator *' 的匹配运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8587024/

相关文章:

c++ - 能否获取成员函数模板参数的所属对象?

c++ - 函数作为模板参数

casting - 使用arrayOfNulls时是否可以删除Kotlin中未经检查的类型转换?

c++ - 有效地收集/分散任务

C++ 扩展函数?

c++ - Windows Phone 运行时组件中的 SQLite

c++ - 如何读取有拼写错误的格式化数据?

c++ - 使用 enable_if 的多个重载问题

c++ - C++ 中的删除运算符是否需要正确的类型?

c++ - 将 const char* 转换为 char* 会崩溃