C++ 如何让编译器为派生类选择方法的非模板版本?

C++ 如何让编译器为派生类选择方法的非模板版本?,c++,templates,inheritance,matrix,C++,Templates,Inheritance,Matrix,我正在编写一个矩阵类(CMatrix),其中包含3d向量(CVector)和旋转矩阵(CRotMatrix)等派生类。我的CMatrix对象可以与另一个基于CMatrix的对象相乘,也可以与任意数值(标量)相乘。 这段代码代表了我遇到的问题的本质: template<class T> class CMatrix { public: template<class U> const CMatrix& operator=(const CMatrix<U

我正在编写一个矩阵类(CMatrix),其中包含3d向量(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;
}

编译器以正确的方式执行此操作,但该类失去了与标量相乘的能力。我用的是msvc10。提前感谢。

原因是模板运算符被视为完全匹配,而矩阵版本需要转换为父引用。因此,编译器选择模板作为更好的匹配

首先考虑如果您真的需要创建的子类,并提供适当的功能/重写。


如果您需要它们,那么我将通过使一个或两个操作都不是运算符来解决问题。通过让
运算符*
执行这两种乘法,您违反了最小意外原则,即让它根据上下文执行两种截然不同的操作。我建议这两种方法都使用命名方法,这样就很明显了,但否则我建议
操作符*
使用矩阵数学,使用函数
ScalarMultiply
来执行单个标量类型。

原因是模板操作符被认为是完全匹配的,而矩阵版本需要转换为父引用。因此,编译器选择模板作为更好的匹配

首先考虑如果您真的需要创建的子类,并提供适当的功能/重写。

如果您需要它们,那么我将通过使一个或两个操作都不是运算符来解决问题。通过让
运算符*
执行这两种乘法,您违反了最小意外原则,即让它根据上下文执行两种截然不同的操作。我建议这两种方法都使用命名方法,所以这是显而易见的,但否则我建议
操作符*
使用矩阵数学,使用函数
ScalarMultiply
使用单个标量类型

问题是编译器更喜欢运算符*()的模板版本。在这种情况下,有没有办法让编译器为派生的CMatrix类选择合适的方法

那是因为你告诉它的。通过标量方法进行的
乘法比通过CMatrix
方法进行的
乘法更通用

将您的“标量乘法”方法设置为注释中所述的方法:

CMatrix& operator*(const T & inp)
{   
    std::cout<<"Multiplication by a scalar."<<std::endl;
    return (*this);
}   
CMatrix和运算符*(常数T和inp)
{   
标准::cout
问题是编译器更喜欢运算符*()的模板版本。在这种情况下,有没有办法让编译器为派生的CMatrix类选择合适的方法

那是因为你告诉它的。你的
用标量
方法进行乘法比你的
用CMatrix
方法进行乘法更通用

将您的“标量乘法”方法设置为注释中所述的方法:

CMatrix& operator*(const T & inp)
{   
    std::cout<<"Multiplication by a scalar."<<std::endl;
    return (*this);
}   
CMatrix和运算符*(常数T和inp)
{   

std::coutWhy有从
CMatrix
派生的单独的
CRotMatrix
类型?对我来说似乎没有必要,因为旋转矩阵可以由普通的
CMatrix
表示。我这样做是因为我希望能够以这种方式初始化旋转矩阵:然后使初始化代码成为非成员函数例如,您可以编写类似于
template void InitRotMatrix(CMatrix&mat,T roll,T pitch,T yaw){}
。这样你就不必创建新类型,代码将是自文档化的。谢谢,我想我会这样做。为什么你有一个独立的
CRotMatrix
类型,它派生自
CMatrix
?对我来说似乎没有必要,因为旋转矩阵可以用普通的
CMatrix
表示,很好。我做了这是因为我希望能够以这种方式初始化旋转矩阵:然后使初始化代码成为非成员函数
。这样,您就不必创建新类型,代码将是自文档化的。谢谢,我想我会这样做。我将此方法变得非常通用,因为我希望我的类与任何数字类型交互,而不仅仅是与实际模板类型交互。例如,矩阵*浮点。我认为我可以将此方法限制在其内部f通过将输入标量转换为实际矩阵类型:
矩阵(i,j)+=(T)INSUCARAR;< /Cord>。如果编译有错误类型,它会在编译过程中出错。不知道它是不是好方法。C++对数值类型进行自动类型升级。函数期望<代码> int >代码>,提供<代码>浮点< /代码>。没问题。代码>。换句话说,
CMatrix和运算符*(T inp)
将完全满足您的要求,并且它不会过于泛型,因此可以匹配所有可能的类型。我之所以将此方法设置为泛型,是因为我希望我的类能够与任何数值类型交互,而不仅仅是与实际的模板类型交互。例如,矩阵*浮点。我认为我可以通过转换将标量输入到实际矩阵类型:
矩阵(i,j)+=(T)INSUCARAR;< /Cord>。如果编译有错误类型,它会在编译过程中出错。不知道它是不是好方法。C++对数值类型进行自动类型升级。函数期望<代码> int >代码>,提供<代码>浮点< /代码>。没问题。code>。换句话说,
CMatrix&operator*(tinp)
将完全满足您的需要,并且它不是过于泛型,它可以匹配所有可能的类型。T