C++库的本征:投给固定大小的矩阵
以下问题:C++库的本征:投给固定大小的矩阵
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)或通过参考< ..>(参见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兼容的方法!
能够完美地与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();
}
根据条件的值,您可以使用C++ 17中的constexpr if,如果值为true
,则丢弃statement-false(如果存在),否则将丢弃statement-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 ...;
}
然后
template<int nDim>
void foo() {
Eigen::Matrix<double, nDim, nDim> bar;
bar = generate_a_special_Matrix<nDim>();
// ... further math here
}
好吧,你用一分钟打我(为模板解决方案) – chtz
尼斯解决方案,谢谢你;但是,我会喜欢坚持GCC 4.8? – macmallow
@macmallow第二种解决方案的问题是什么? – songyuanyao
如果您正在使用C++ 17,你可以写
if constexpr (nDim == 3){ bar = generate_a_special_3x3_Matrix();}
等,但你可以很容易地通过templatizing实现C++ 03兼容的解决方案您的generate_a_special_nxn_Matrix
功能:
// 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
}
谢谢,您的C++ 03可以,但是,它隐藏了实际的操作,因此在目前的情况下并不适合。 C++ 17的方法很好,但我需要坚持GCC 4.8。 – macmallow
本案例中的完美解决方案!谢谢! – macmallow