2015-01-02 59 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."); 
    //   ~~~~~~~~~~~~~~~^ 
}; 
相关问题