mas*_*oud 0 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 ...//
Run Code Online (Sandbox Code Playgroud)
身体写得很好,一切都运作良好.当我定义两个矩阵时如下:
Matrix < 10, 10, int> m1;
Matrix < 10, 10, float> m2;
m1 + m2; // OK
m1 * m2; // error: no match for 'operator*' in 'm1 * m2'
Run Code Online (Sandbox Code Playgroud)
第一个'+'运算符运行良好,因为已对其执行了隐式转换.但对于不同值类型的第二个'*'运算符,会发生错误.
错误:'m1*m2'中'operator*'不匹配
任何的想法 ?!
更新: 所有代码都在头文件中.对于'*'运算符我没问题.
您对"+"运算符的看法是什么?我知道关于模板/运算符/转换的一切......但是这个问题就像我的gcc编译器的一个错误!?我写了一个cast-operator,这个运算符在'+'运算符之前调用,但我不知道为什么它不能为'*'运算符执行!
问题或多或少是经典的.重载解决方案首先建立一个可能的功能列表; 在这种情况下,函数命名
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;
Run Code Online (Sandbox Code Playgroud)
,然后在运营商*内进行转换.(我没有尝试过,我也不确定,但我认为你的现有operator*应该被认为是"更专业化",因此当两种类型的扣除成功时就会选择它.)
话虽如此,我认为你这样做的方法是错误的.你真的想要返回类型m1 * m2和m2 * m1不同.对于初学者,我需要客户端代码使转换显式(在当前代码中就是这种情况); 如果你确实想支持隐式转换,我认为你需要创建
operator*一个全局,使用某种简单的元编程来确定正确的返回类型(即给定矩阵的long和
unsigned,你可能希望有一个返回类型unsigned long,因为这是这些类型的混合类型算术否则),将双方转换为目标类型,并对其进行算术运算.很多工作可能不是一个非常重要或有用的功能.(当然,我的意见.如果你的客户真的想要混合型算术,并且愿意付钱......)
| 归档时间: |
|
| 查看次数: |
1742 次 |
| 最近记录: |