我正在使用特征线性代数库(link)中的模板化Matrix类。 Matrix类采用三个标称模板参数:
Matrix<type, rows, cols>
在上文中,type
的示例是double
或std::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指针。
答案 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;
// ...
}
您可以使用预处理器定义切换这些定义。