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

时间:2018-11-29 14:14:52

标签: c++ sfinae static-assert

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

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>>();
}

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

1 个答案:

答案 0 :(得分:6)

  

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

是的。静态断言是在X的实例中,而不是在模板函数的直接上下文中。因此,它不会仅仅是替换失败,程序会格式错误。有(尽管不是规范性的)注释,应该进一步支持这种方式。

  

[扣除温度] (强调注释)

     

8如果替换导致无效的类型或表达式,请键入   推论失败。无效的类型或表达式将是   格式错误,且需要诊断,如果使用   替代参数。 [注意:如果不需要诊断,则   程序仍然格式不正确。访问检查是作为   替代过程。 — end note]仅无效的类型和表达式   在函数类型及其模板的直接上下文中   参数类型可能会导致推导失败。 [注意:   替换为类型和表达式可能会导致诸如   类模板专业化和/或功能的实例化   模板专业化,隐式定义的生成   功能等。此类影响不在“即时上下文”中,并且   可能会导致程序格式错误。 —尾注]

在您的特定情况下,让X对SFINAE友好也很简单:

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

甚至

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