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