在SFINAE上下文中使用的表达式中使用的static_assert

Kla*_*aus 3 c++ static-assert sfinae

如果我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>>();
}
Run Code Online (Sandbox Code Playgroud)

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

Sto*_*ica 6

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

是.静态断言是在X模板函数的实例化中,而不是在模板函数的直接上下文中.所以它不仅仅是替代失败,该计划将是不正确的.有一个(尽管是非规范性的)注释,进一步支持这应该是这样的.

[temp.deduct](注意强调)

8如果替换导致无效的类型或表达式,则类型推导失败.如果使用替换参数写入,则无效的类型或表达式将是格式错误的,需要诊断.[注意:如果不需要诊断,程序仍然是不正确的.访问检查是替换过程的一部分. - 结束注释]只有函数类型的直接上下文中的无效类型和表达式及其模板参数类型才会导致演绎失败.[注意:替换为类型和表达式可能会产生诸如类模板特化和/或函数模板特化的实例化,隐式定义函数的生成等效果.这些效果不在"直接上下文"中,并且可以导致程序格式不正确. - 结束说明]

在您的特定情况下,使XSFINAE友好也是相当直接的:

// No static assertion
static constexpr bool value = (i != 4);
Run Code Online (Sandbox Code Playgroud)

甚至

template <int i>
struct X : std::bool_constant< i != 4 >{};
Run Code Online (Sandbox Code Playgroud)