本征库:模板中的断言失败

Eigen Library: Assertions failed in a template

我有一个模板化函数,它应该生成一个编译时已知的固定大小 Vector,具体取决于模板参数:

template <int nSize> 
Eigen::Matrix<double, nSize, 1> myFunc()
{
    switch(nSize){
    case 2: return ExternalLibrary::generate_Vector_2d();
    case 3: return ExternalLibrary::generate_Vector_3d();
    }
}

但是,当我编译这段代码时,我得到了一个失败的断言,因为 Vector_2d 尺寸不适合 3d 尺寸:

Eigen::Vector3d testVector3d = myFunc<3>(); // failed, because 3d doesn't fit the theoreticelly possible 2d 

基本上,失败的断言是可以理解的,但当然这在运行时永远不会成为问题。我怎样才能绕过这个失败的断言?或者有没有比switch条件更优雅的方式?

谢谢!

只声明模板函数,不定义它,然后定义两个特化:

template <int nSize>
Eigen::Matrix<double, nSize, 1> myFunc();

template <>
Eigen::Matrix<double, 2, 1> myFunc<2>()
{
    return ExternalLibrary::generate_Vector_2d();
}

template <>
Eigen::Matrix<double, 3, 1> myFunc<3>()
{
    return ExternalLibrary::generate_Vector_3d();
}

编译器,虽然它会消除死代码作为优化,无论如何都必须验证死代码的有效性,这意味着它必须确保 return ExternalLibrary::generate_Vector_3d() 的类型可以转换为 Eigen::Matrix<double, 2, 1>,即使可以证明 return 语句无法执行。因为不允许这种转换,所以会出现编译时错误。

通过将两个 return 语句分离到单独的专业化中,您消除了这个问题,因为它从函数中删除了 return ExternalLibrary::generate_Vector_3d(); 语句, 可以 return Eigen::Matrix<double, 3, 1>.

以外的东西

请注意,将 myFunc() 与 2 或 3 以外的 nSize 一起使用会导致 link 时错误。我们可以通过提供无法实例化的主体将此错误移至编译时,但(表面上)依赖于 nSize 以便编译器不会在使用之前尝试实例化它:

template <int nSize>
Eigen::Matrix<double, nSize, 1> myFunc()
{
    // With C++11, the following line provides a more useful diagnostic. If
    // you don't have C++11 support, remove it and the bad return statement
    // will do the job, albeit with a more cryptic error message.
    static_assert((static_cast<void>(nSize), false), "Invalid template parameter nSize");

    return static_cast<class INVALID_NSIZE_PARAMETER**********>(nSize);
}

这将提供指向错误使用 myFunc() 的诊断。例如,如果没有 C++11 支持,您会看到类似以下内容:

main.cpp:12:12: error: cannot cast from type 'int' to pointer type 'class INVALID_NSIZE_PARAMETER **********'
    return static_cast<class INVALID_NSIZE_PARAMETER**********>(nSize);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:29:5: note: in instantiation of function template specialization 'myFunc<4>' requested here
    myFunc<4>();
    ^