static_assert используется в выражении, которое используется в контексте SFINAE - PullRequest
0 голосов
/ 29 ноября 2018

Если я использую 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 Ответ

0 голосов
/ 29 ноября 2018

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

Да.Статическое утверждение находится в экземпляре 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 >{};
...