C++ 为什么“static_assert”总是被调用?

C++ 为什么“static_assert”总是被调用?,c++,c++11,static-assert,C++,C++11,Static Assert,如果USE\u STATIC\u ASSERT为0,这将按预期工作(从列表中获取索引类型)。如果1,则静态断言()总是被触发。我本以为只有当所有的typenames都用尽时,static\u assert()才会发生。为什么不是这样 #define USE_STATIC_ASSERT 1 template <unsigned int I, typename ...Ts> struct items; template <typename T, typename ...Ts>

如果
USE\u STATIC\u ASSERT
0
,这将按预期工作(从列表中获取索引类型)。如果1,则
静态断言()
总是被触发。我本以为只有当所有的
typename
s都用尽时,
static\u 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;
}
#定义使用静态断言1
模板
结构项目;
模板
结构项
{
T型;
};
模板
结构项目:项目
{
};
#如果使用静态断言
模板
结构项
{
静态_断言(false,“用完Ts.”;
};
#恩迪夫
int main()
{

cout即使未实例化包含
静态断言的
项的部分专门化,编译器也可以根据§14.6[temp.res]/p8拒绝此代码:

知道哪些名称是类型名称可以检查每个模板的语法。无需诊断 应针对可生成有效专门化的模板发布。如果无法为模板生成有效专门化,且该模板未实例化,则该模板格式错误,无需诊断。

要解决这个问题,您可以使
static\u 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.");
    //            ~~~~~~~~~~~~~~~^
};
#包括
模板
结构AlwaysFalse:std::false_type{};
模板
结构项
{
静态断言(AlwaysFalse{},“用完了Ts.”;
//            ~~~~~~~~~~~~~~~^
};

即使未实例化包含
静态断言的
项的部分专用化,编译器也可以根据§14.6[temp.res]/p8拒绝此代码:

知道哪些名称是类型名称可以检查每个模板的语法。无需诊断 应针对可生成有效专门化的模板发布。如果无法为模板生成有效专门化,且该模板未实例化,则该模板格式错误,无需诊断。

要解决这个问题,您可以使
static\u 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.");
    //            ~~~~~~~~~~~~~~~^
};
#包括
模板
结构AlwaysFalse:std::false_type{};
模板
结构项
{
静态断言(AlwaysFalse{},“用完了Ts.”;
//            ~~~~~~~~~~~~~~~^
};