2017-06-05 69 views
0

我有一个模板函数,它应该产生一个编译时已知固定大小的矢量,取决于模板参数:征库:断言失败模板

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 

基本上,失败的断言是可以理解的,但当然这绝不会在运行时的问题。我怎样才能绕过这个失败的断言?还是有比开关条件更优雅的方式?

谢谢!

+0

为什么不[完全专注(http://en.cppreference.com/w/cpp/language/template_specialization)的FUNC模板? –

回答

3

只是声明模板功能,但没有定义它,然后定义两个专业:

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(); 
} 

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

通过分离出两个return语句为独立的专业化,你消除这个问题,因为它从一个函数删除return ExternalLibrary::generate_Vector_3d();声明可能不是Eigen::Matrix<double, 3, 1>其他回报。


注意,使用与myFunc()大于2或3以外的nSize将导致一个链路时错误。在使用前,我们可以将这个错误提供了一个机构,将无法实例化编译时间,但是这(表面上)依赖于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>(); 
    ^
+0

这是一个完美的答案,谢谢!我的代码已经工作。 – macmallow