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

Это поведение, которое мы должны ожидать?

1 ответ

Решение

Это поведение, которое мы должны ожидать?

Да. Статическое утверждение заключается в создании X а не в непосредственном контексте функции шаблона. Так что это не будет простой ошибкой замещения, программа будет некорректной. Существует (хотя и ненормативное) примечание, что дальнейшая поддержка должна быть именно такой.

[temp.deduct] (с примечанием выделено)

8 Если подстановка приводит к неверному типу или выражению, вывод типа завершается неудачно. Недопустимый тип или выражение - это тип, который был бы неправильно сформирован, с необходимостью диагностики, если он записан с использованием замещенных аргументов. [Примечание: если диагностика не требуется, программа все еще не работает. Проверка доступа выполняется как часть процесса замены. - примечание конца] Только недопустимые типы и выражения в непосредственном контексте типа функции и ее типов параметров шаблона могут привести к ошибке вывода. [Примечание: замена на типы и выражения может привести к таким эффектам, как создание экземпляров специализаций шаблонов классов и / или специализаций шаблонов функций, генерация неявно определенных функций и т. Д. Такие эффекты находятся не в "непосредственном контексте" и могут В результате программа будет плохо сформирована. - конец примечания]

В вашем конкретном случае, делая X SFINAE дружелюбен и довольно прост:

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

Или даже

template <int i>
struct X : std::bool_constant< i != 4 >{};
Другие вопросы по тегам