2015-01-02 61 views
0

如果​​爲0,則按預期工作(從列表中獲取索引類型)。如果1 static_assert()總是跳閘。我會認爲static_assert()只會發生在所有的typename都用完了。爲什麼不是這樣?爲什麼`static_assert`總是被調用?

#define USE_STATIC_ASSERT 1 
template <unsigned int I, typename ...Ts> 
struct items; 

template <typename T, typename ...Ts> 
struct items<0, T, Ts...> 
{ 
    typedef T type; 
}; 

template <unsigned int I, typename T, typename ...Ts> 
struct items<I, T, Ts...> : items<I-1, Ts...> 
{ 
}; 

#if USE_STATIC_ASSERT 
template <unsigned int I> 
struct items<I> 
{ 
    static_assert(false, "Ran out of Ts."); 
}; 
#endif 


int main() 
{ 
    cout << is_same<float, items<1, int, float, double>::type>::value << endl; 
} 

回答

5

即使包含static_assertitems部分特沒有實例化,編譯器允許根據§14.6[temp.res]/P8到拒絕這樣的代碼:

知道哪些名稱是類型名稱允許檢查每個模板的語法。對於可以生成有效專業化的模板,不得發佈診斷 。 如果不能爲模板生成有效的特化,並且該模板未實例化,則該模板不合格,不需要診斷。

要解決的是,你可以在依賴於其他類模板static_assert表達:

#include <type_traits> 

template <unsigned int I> 
struct AlwaysFalse : std::false_type {}; 

template <unsigned int I> 
struct items<I> 
{ 
    static_assert(AlwaysFalse<I>{}, "Ran out of Ts."); 
    //   ~~~~~~~~~~~~~~~^ 
}; 
相關問題