使用条件语句在运行时选择不同的模板矩阵类

时间:2012-12-06 21:19:37

标签: c++ templates pointers eigen

我正在使用特征线性代数库(link)中的模板化Matrix类。 Matrix类采用三个标称模板参数:

Matrix<type, rows, cols>

在上文中,type的示例是doublestd::complex<double>。此外,rows是行数,cols是矩阵中的列数。

如下面的代码所示,我想要做的是在运行时使用条件语句使用不同的模板化Matrix类。

首先想到的解决方案可能是使用void指针。

#include <iostream>
#include <Eigen/Dense>
#include <complex>

using namespace Eigen;

int main()

{  
    // this flag is set at run-time, but it is only set here
    // in the code as an example
    int create_complex = 1;
    void *M;

        if(create_complex)
    {
        Matrix<std::complex<double>,3,3> m0;
        M = &m0;
    }
    else
    {
        Matrix<double,3,3> m0;
        M = &m0;
    }
    // de-reference pointer here and use it    

 return 0;
}

虽然此代码编译,但void *M指针需要在使用前显式解除引用。这很不方便,因为我必须为相同的程序逻辑编写不同的代码块。

我想知道是否存在类似于可能在这里应用的多态的东西,我不必使用void指针。

3 个答案:

答案 0 :(得分:2)

  

这很不方便

如果您将“不方便”视为“非法”,那么您就会被发现。

局部变量在其范围结束时被销毁(即结束}),因此你留下了一个悬空指针。因此,在尝试取消引用时,您将遇到未定义的行为。

没有简单的方法可以做到这一点,因为Matrix<std::complex<double>,3,3>Matrix<double,3,3>是完全不相关的类。我会再说一遍。 他们是完全不相关的课程

另一种选择是Matrix有一个基类型,你有一个指向它的指针,但是你需要动态分配。类似的东西:

BaseMatrix* m;
if ()
    m = new Matrix<std::complex<double>,3,3>;
else 
    m = new Matrix<double,3,3>;

答案 1 :(得分:2)

您可以根据矩阵类型将自己的函数编写为模板,并在条件语句中调用它的不同版本。

这是唯一的方法,因为模板用于在编译时生成代码。 必须在编译时生成所有代码路径,然后只选择其中一个。

答案 2 :(得分:1)

你也应该模仿你的方法:

template<class T>
my_main() { 

   Matrix<T,3,3> m0;

   // ...


}

<强>更新

或者您可以定义您的班级

#ifndef CREATE_COMPLEX
    typedef double MyClass;
#else
    typedef std::complex<double> MyClass;
#endif

main() { 

   Matrix<MyClass,3,3> m0;

   // ...


}

您可以使用预处理器定义切换这些定义。