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 >{};