首页 > 解决方案 > 在 SFINAE 上下文中使用的表达式中使用的 static_assert

问题描述

如果我static_assert在 SFINAE 的条件内使用,编译器会发出错误并停止。

template < int i>
class X
{
    static_assert( i != 4 );
    public:
        static constexpr bool value = true;
};

    template < typename T >
typename std::enable_if< T::value, void>::type Do(  )
{
    std::cout << "one" << std::endl;
}

    template < typename T >
typename std::enable_if< !T::value, void>::type Do( )
{
    std::cout << "two" << std::endl;
}


int main()
{
    Do<std::true_type>();
    Do<std::false_type>();

    // ###########
    Do<X<1>>();
    Do<X<4>>();
}

这是我们应该期待的行为吗?

标签: c++sfinaestatic-assert

解决方案


这是我们应该期待的行为吗?

是的。静态断言是在 的实例化中X,而不是在模板函数的直接上下文中。所以这不仅仅是替换失败,程序将是错误的。有一个(尽管是非规范性的)说明进一步支持这应该是这种方式。

[temp.deduct](强调注)

8如果替换导致无效的类型或表达式,则类型推导失败。无效类型或表达式是一种格式错误的类型或表达式,如果使用替换参数编写,则需要进行诊断。[ 注意:如果不需要诊断,程序仍然是格式错误的。访问检查是替换过程的一部分。— end note ] 只有在函数类型及其模板参数类型的直接上下文中的无效类型和表达式会导致推导失败。[ 笔记:对类型和表达式的替换可能会导致类模板特化和/或函数模板特化的实例化、隐式定义函数的生成等效果。这些效果不在“直接上下文”中,并且可能导致程序格式错误。——尾注]

在您的特定情况下,使XSFINAE 友好也相当简单:

// No static assertion
static constexpr bool value = (i != 4);

甚至

template <int i>
struct X : std::bool_constant< i != 4 >{};

推荐阅读