2017-06-05 107 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