0

我正在使用 Eigen 线性代数库(链接)中的模板化 Matrix 类。Matrix 类采用三个名义模板参数:

Matrix<type, rows, cols>

在上面,typedouble或的一个例子std::complex<double>。此外,rows是行cols数, 是 Matrix 中的列数。

如下面的代码所示,我想做的是在运行时使用条件语句使用不同的模板化 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 指针。

4

3 回答 3

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>;
于 2012-12-06T21:22:40.423 回答
2

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

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

于 2012-12-06T21:24:28.927 回答
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;

   // ...


}

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

于 2012-12-06T21:26:22.413 回答