我有一个矩阵类如下:
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'第一个'+‘操作符运行良好,因为隐式强制转换已经在其上执行。但对于不同值类型的第二个“*”运算符,则会发生错误。
错误:与“m1*m2”中的“运算符*”不匹配
知道吗?!
更新:所有代码都在头文件中。除了“*”接线员之外,我没有任何问题。
关于“+”操作符你能说些什么?我对模板/操作符/铸造了如指掌。但是这个问题对我的gcc编译器来说就像一个错误!?我写了一个转换操作符,这个操作符在'+‘操作符之前调用,但是我不知道为什么它不执行'*’操作符!
发布于 2011-12-21 09:23:22
这个问题或多或少是典型的。重载解析首先构建一个可能的函数列表;在本例中,是名为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*应该被认为是“更专业的”,因此,当类型推导成功时,应该选择两者。)
话虽如此,我认为你这样做是错误的。您真的希望m1 * m2和m2 * m1的返回类型不同吗?首先,我要求客户端代码将转换显式化(在当前代码中是如此);如果您确实希望支持隐式转换,我认为您需要将operator*变成全局的,使用某种简单的元编程来确定正确的返回类型(例如,给定long和unsigned的矩阵,您可能希望有一个unsigned long的返回类型,因为这就是混合类型算法与这些类型所提供的),将两边转换为目标类型,并对其执行算法。对于可能不是非常重要或有用的特性,做了大量的工作。(当然,这只是我的观点。如果你的客户真的想要混合类型的算术,并且愿意为此付钱.)
发布于 2011-12-21 09:10:06
隐式强制转换是示例中的罪魁祸首(m1 * m1工作)。虽然我的语言不够坚定,无法确切地告诉您为什么,但我怀疑模板运算符*方法(它没有精确地指定类型)和必要的类型转换的组合有太多的模糊性。编译器被告知它可以将您的矩阵转换成任何类型,并且模板化的类型系列可能是operator*的有效参数。在确定从这些方法调用哪个operator*时,我会遇到问题。插入static_cast作为m1 * static_cast< Matrix<10,10,int> >(m2)确认了这种怀疑。
本征库是一个相当成熟和非常好的矩阵库,它们也不进行隐式标量转换。相反,他们采用了一种铸造方法:
template <typename Scalar> Matrix<M,N,Scalar> cast() const;在你的例子中,你会写:
m1.cast<float>() * m2; https://stackoverflow.com/questions/8587024
复制相似问题