如何让编译器为派生类选择方法的非模板版本
How to make the compiler choose the non-template version of a method for derived classes?
我正在编写一个矩阵类(CMatrix(,其中包含诸如三维向量(CVector(和旋转矩阵(CRotMatrix(之类的派生类。我的CMatrix对象可以与另一个基于CMatrix的对象相乘,也可以与任何数值(标量(相乘。这段代码代表了我遇到的问题的本质:
template<class T> class CMatrix
{
public:
template<class U> const CMatrix& operator=(const CMatrix<U> &inp){return (*this);}
CMatrix& operator*(const CMatrix &inp)
{
cout<<"Multiplication by CMatrix"<<endl;
return (*this);
}
template<class U>
CMatrix& operator*(const U &inp)
{
cout<<"Multiplication by a scalar."<<endl;
return (*this);
}
};
template<class T> class CVector: public CMatrix<T>{};
template<class T> class CRotMatrix: public CMatrix<T>{};
int main()
{
CMatrix<int> foo1;
CMatrix<int> foo2;
CVector<int> dfoo1;
CRotMatrix<int> dfoo2;
foo1 = foo1*foo2; //calls CMatrix method
foo1 = foo1*5; //calls scalar method
foo1 = foo1*dfoo2; //calls scalar method, shoud be CMatrix
foo1 = dfoo2*dfoo1; //calss scalar method, shoud be CMatrix
return 0;
}
问题是编译器更喜欢运算符*((的模板版本。在这种情况下,有什么方法可以让编译器为派生的CMatrix类选择正确的方法吗?如果我切断这种方法
CMatrix& operator*(const U &inp)
编译器以正确的方式执行,但类失去了与标量相乘的能力。我在用msvc10。提前谢谢。
原因是模板运算符被认为是完全匹配的,而矩阵版本需要转换为父引用。因此,编译器选择模板作为更好的匹配。
首先考虑您是否真的需要创建的子类,以及它们是否提供了适当的功能/覆盖。
如果你需要它们,那么我会通过使其中一个或两个操作而不是运算符来解决问题。让operator*
做两种乘法,违反了最小惊喜原则,让它根据上下文做两种截然不同的事情。我建议两者都使用命名方法,所以这是显而易见的,但除此之外,我建议operator*
为矩阵数学,函数ScalarMultiply
为单个标量类型。
问题是编译器更喜欢运算符*((的模板版本。在这种情况下,有什么方法可以让编译器为派生的CMatrix类选择正确的方法吗?
这是因为你告诉它。你的Multiplication by a scalar
方法比你的Multiplication by CMatrix
方法更通用。
让你的"标量乘"方法成为评论所说的:
CMatrix& operator*(const T & inp)
{
std::cout<<"Multiplication by a scalar."<<std::endl;
return (*this);
}
附录
您的template<class U> CMatrix& operator*(const U &inp)
是如此通用,以至于它匹配任何。多重std::istream
:没问题。它打印Multiplication by a scalar.
你希望你与标量的乘积是有限制的,而不是任何随机类型的包罗万象。
- VS2017 版本 15.8.3 成功编译内联方法,而不返回所需值
- 获取Windows版本的正确方法
- 将用户输入绑定到UE4.22.3及更高版本中的UActorComponent方法
- 设置用G 构建的二进制版本的任何方法
- 拥有相同方法的静态和非静态版本是不是设计不好
- 使用 C++17 或更高版本对向量中的元素对求和的最'functional'方法?
- 在C 11或更高版本中,是否可以通过Lambda来实现单方法纯Virtual C 接口
- 最新版本的 Boost asio 库中缺少方法的替代方法
- 使用其范围版本从容器中删除元素的最佳方法
- 使用 C# 获取 OpenGL 版本的最简单方法
- 建议在我的C 库中管理版本的方法
- 为什么较新版本的C++不允许在类声明中定义纯方法?
- 当模板参数为std::vector时,如何创建此方法的模板版本
- 有哪些好方法可以对二进制打包的结构消息进行版本化
- C++ 是在每个实例化上创建的模板类中每个方法的新版本
- 设计方法以读/编写同一配置文件的不同版本
- 无论CRT版本如何,这都是在库中提供STL函数的有效方法吗
- C/CPP 宏或预处理器,用于处理方法的多个版本
- DialogBoxParam()方法未调用IE 9或更高版本中的GUI
- C++堆栈实现 - 两个版本的 top 方法