以下问题:
template<int nDim>
void foo ( ){
Eigen::Matrix<double, nDim, nDim> bar;
if ( nDim == 3 ){
bar = generate_a_special_3x3_Matrix();}
else if ( nDim == 2 ){
bar = generate_a_special_2x2_Matrix();}
// ... further math here
}
因此,当然由于静态断言,此代码无法编译。 但是,保证在运行时不会出现问题。
目前已知的解决方案是通过.block(3,3)或通过Ref&lt; ..&gt;进行分配。 (参见Cast dynamic matrix to fixed matrix in Eigen)。
.block方法:
template<int nDim>
void foo ( ){
Eigen::Matrix<double, nDim, nDim> bar;
if ( nDim == 3 ){
bar.block(3,3) = generate_a_special_3x3_Matrix();}
else if ( nDim == 2 ){
bar.block(2,2) = generate_a_special_2x2_Matrix();}
// ... further math here
}
然而,这两种方法都涉及运行时检查正确的矩阵大小,这些并不是必需的,并且编写的代码并不是很漂亮。
我并不真正关心运行时开销(尽管避免使用它会很好),但编写的代码在我看来并不是很干净,因为.block()的意图并不是很明显。其他。 是否有更好的方法,例如像演员这样的东西?
编辑:发布了两个好的解决方案(如果是constexpr),但是,我需要一个C ++ 11/14兼容的方法!
答案 0 :(得分:3)
你可以根据条件的值使用C ++ 17中的constexpr if,如果值是U604 LRRC69
U586 PLEKHA5,C8orf77,ZNF252,LINGO2
U531 5S_rRNA,C3orf33
S784 CHST5,TMEM231,TM4SF20,TMEM184A
,则丢弃statement-false(如果存在),否则,statement-true被丢弃;然后代码不会导致编译错误。 e.g。
true
或制作template<int nDim>
void foo () {
Eigen::Matrix<double, nDim, nDim> bar;
if constexpr ( nDim == 3 ) {
bar = generate_a_special_3x3_Matrix();
} else constexpr if ( nDim == 2 ) {
bar = generate_a_special_2x2_Matrix();
}
// ... further math here
}
功能模板,例如
generate_a_special_Matrix
然后
template <int nDim>
Eigen::Matrix<double, nDim, nDim> generate_a_special_Matrix();
template <>
Eigen::Matrix<double, 2, 2> generate_a_special_Matrix<2>() {
... generating ...
return ...;
}
template <>
Eigen::Matrix<double, 3, 3> generate_a_special_Matrix<3>() {
... generating ...
return ...;
}
答案 1 :(得分:1)
如果您使用的是C ++ 17,则可以编写
if constexpr ( nDim == 3 ){ bar = generate_a_special_3x3_Matrix();}
等。但是,您可以通过模板化generate_a_special_nxn_Matrix
函数轻松实现C ++ 03兼容解决方案:
// general declaration (without implementation):
template<int nDim>
Eigen::Matrix<double, nDim, nDim> generate_a_special_nxn_Matrix();
template<>
Eigen::Matrix<double, 2, 2> generate_a_special_nxn_Matrix(){
return generate_a_special_2x2_Matrix();
}
template<>
Eigen::Matrix<double, 3, 3> generate_a_special_nxn_Matrix(){
return generate_a_special_3x3_Matrix();
}
然后直接调用
template<int nDim>
void foo ( ){
Eigen::Matrix<double, nDim, nDim> bar = generate_a_special_nxn_Matrix<nDim>();
// ... further math here
}
答案 2 :(得分:1)
要优雅地坚持使用c ++ 98,您可以滥用comma initializer语法:
template<int N>
void foo(){
Eigen::Matrix<double, N, N> bar;
if(N==3) bar << Matrix3d();
else if(N==2) bar << Matrix2d();
}