Обновления в отношениях static_assert и if constexpr



Наш подписчик Вадим упомянул о важном изменении в отношениях static_assert и if constexpr. Эти изменения вступили в силу с приходом С++23 и говорят о том, что теперь программа не считается ill-formed, даже если static_assert фейлится для всех специализаций.



Посмотрим на уже заезженном примере:



template <typename T>

std::string to_str(T t) {

if constexpr (std::is_constructible_v<std::string, T>)

return t;

else if constexpr (std::is_arithmetic_v<T>)

return std::to_string(t);

else

static_assert(false, "cannot convert type to std::string");

}



class A{};



int main()

{

std::cout << to_str("qwe") << std::endl; // OK

std::cout << to_str(5.0) << std::endl; // OK

std::cout << to_str(A{}) << std::endl; // static_assert failed

}





Создали структуру пустышку и использовали функцию to_str по всем трем веткам условия. И если закомментировать последний вывод в консоль - все корректно компилируется и выполняется. Но как только мы инстанцируем специализацию с пессимистичной веткой условия, компиляция падает на ассерте.



Не у многих есть возможность попробовать 23-е плюсы на своих машинках, поэтому оставлю ссылку на годболт, чтобы вы могли поиграться с примером.



До прихода 23-х плюсов была очевидная проблема с этим static_assert'ом. Вроде бы это очень логично писать условия как в примере выше и ожидать, что это сработает. Да и наличие смешного донельзя воркэраунда с шаблонным типозависимым выражением, которое все равно возвращает false, как бы намекает, что что-то не так. Радостно видеть развитие языка и закрытие таких болючих пробелов.



Fix your flaws. Stay cool.



#cpp23 #template