为什么总是要调用“ static_assert”? [英] Why does the `static_assert` always get invoked?

查看:65
本文介绍了为什么总是要调用“ static_assert”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果 USE_STATIC_ASSERT 0 ,则按预期方式工作(从列表中获取索引类型)。如果为1,则始终断开 static_assert()。我本以为 static_assert()仅在所有 typename 用尽时才会发生。为什么不是这样?

If USE_STATIC_ASSERT is 0, this works as expected (getting indexed type from the list). If 1 the static_assert() is always tripped. I would have thought that the static_assert() would only happen if all the typenames were exhausted. Why is this not so?

#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;
}


推荐答案

即使部分专业化包含 static_assert 未实例化,允许编译器根据§14.6[temp。 res] / p8:

Even if the partial specialization of items that contains the static_assert is not instantiated, the compiler is allowed to reject this code according to §14.6 [temp.res]/p8:


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

要解决此问题,可以使 static_assert 中的表达式依赖于其他类模板:

To work around that, you can make the expression in static_assert dependent on other class template:

#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.");
    //            ~~~~~~~~~~~~~~~^
};

这篇关于为什么总是要调用“ static_assert”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆