首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >矩阵中“运算符*”的无匹配运算符

矩阵中“运算符*”的无匹配运算符
EN

Stack Overflow用户
提问于 2011-12-21 08:40:33
回答 2查看 2.4K关注 0票数 0

我有一个矩阵类如下:

代码语言:javascript
复制
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  ...//

身体写得很好,一切都很好。当我将两个矩阵定义如下:

代码语言:javascript
复制
Matrix < 10, 10, int> m1;
Matrix < 10, 10, float> m2;

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

第一个'+‘操作符运行良好,因为隐式强制转换已经在其上执行。但对于不同值类型的第二个“*”运算符,则会发生错误。

错误:与“m1*m2”中的“运算符*”不匹配

知道吗?!

更新:所有代码都在头文件中。除了“*”接线员之外,我没有任何问题。

关于“+”操作符你能说些什么?我对模板/操作符/铸造了如指掌。但是这个问题对我的gcc编译器来说就像一个错误!?我写了一个转换操作符,这个操作符在'+‘操作符之前调用,但是我不知道为什么它不执行'*’操作符!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-21 09:23:22

这个问题或多或少是典型的。重载解析首先构建一个可能的函数列表;在本例中,是名为operator*的函数。为此,它将范围内的所有operator*函数添加到列表中,并尝试通过应用类型演绎来实例化所有函数模板;如果类型演绎成功,则将模板的实例化添加到列表中。(函数模板是而不是函数。函数模板的实例化是一个函数。)

模板类型推断的规则与重载解析中使用的规则不同。特别是,只考虑非常小的一组转换。不考虑用户定义的转换运算符。结果是,在m1 * m2中,operator*的类型扣减失败(因为它需要不考虑的转换)。因此,没有将函数模板的实例化添加到列表中,也没有其他operator*

更普遍的情况是:您是operator T2(),即使允许,也不允许进行类型推断;有无限数量的转换将与operator*匹配。事实上,我怀疑你把它变得太笼统了;你想要一个operator Matrix<M, N, T2>()。(这并不是说这会有帮助,但在某些情况下,它可能会消除歧义。)

您可能可以通过定义一个:

代码语言:javascript
复制
template<size_t P, tyepname OtherT>
Matrix<M, P, T> operator*( Matrix<N, P, T> const& rhs ) const;

,然后在操作符内执行转换*。(我还没有试过,也不确定,但我认为您现有的operator*应该被认为是“更专业的”,因此,当类型推导成功时,应该选择两者。)

话虽如此,我认为你这样做是错误的。您真的希望m1 * m2m2 * m1的返回类型不同吗?首先,我要求客户端代码将转换显式化(在当前代码中是如此);如果您确实希望支持隐式转换,我认为您需要将operator*变成全局的,使用某种简单的元编程来确定正确的返回类型(例如,给定longunsigned的矩阵,您可能希望有一个unsigned long的返回类型,因为这就是混合类型算法与这些类型所提供的),将两边转换为目标类型,并对其执行算法。对于可能不是非常重要或有用的特性,做了大量的工作。(当然,这只是我的观点。如果你的客户真的想要混合类型的算术,并且愿意为此付钱.)

票数 6
EN

Stack Overflow用户

发布于 2011-12-21 09:10:06

隐式强制转换是示例中的罪魁祸首(m1 * m1工作)。虽然我的语言不够坚定,无法确切地告诉您为什么,但我怀疑模板运算符*方法(它没有精确地指定类型)和必要的类型转换的组合有太多的模糊性。编译器被告知它可以将您的矩阵转换成任何类型,并且模板化的类型系列可能是operator*的有效参数。在确定从这些方法调用哪个operator*时,我会遇到问题。插入static_cast作为m1 * static_cast< Matrix<10,10,int> >(m2)确认了这种怀疑。

本征库是一个相当成熟和非常好的矩阵库,它们也不进行隐式标量转换。相反,他们采用了一种铸造方法:

代码语言:javascript
复制
template <typename Scalar> Matrix<M,N,Scalar> cast() const;

在你的例子中,你会写:

代码语言:javascript
复制
m1.cast<float>() * m2;  
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8587024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档