В constexpr функциях можно использовать static_assert в if..else конструкциях.
Например,
template<typename T>
constexpr int mypow(T&& b)
{
if constexpr(std::is_same_v<T, int>) {
return b*2;
}
else {
static_assert(false, "type is not supported");
}
}
Компиляция закончится ошибкой только если функция будет инстанциированна отличным от int типом.
Так же можно использовать исключения в constexpr функциях.
template<typename T>
constexpr int mypow(T&& b)
{
if constexpr(std::is_same_v<T, int>) {
return b*2;
}
throw std::runtime_error{"type is not supported"};
}
Компилятор может отслеживать поток выполнения приложения. Таким образом, функция является constexpr, если выполняется условие.
Однако, та же логика не работает для static_assert и if..else конструкции. Следующий код не скопилируется, даже если вызвать с int типом. Компилятор в любов случае фэйлится на static_assert.
template<typename T>
constexpr int mypow(T&& b)
{
if constexpr(std::is_same_v<T, int>) {
return b*2;
}
static_assert(false, "type is not supported");
}
Мое предложение - не проверять static_assert в терминальном случае.
Достоинства:
Код выглядит немного чище, чем с else веткой.
Сохранится последовательность когда используется throw.
Мотивация
В
constexpr
функциях можно использоватьstatic_assert
в if..else конструкциях.Например,
Компиляция закончится ошибкой только если функция будет инстанциированна отличным от
int
типом. Так же можно использовать исключения вconstexpr
функциях.Компилятор может отслеживать поток выполнения приложения. Таким образом, функция является
constexpr
, если выполняется условие.Однако, та же логика не работает для
static_assert
и if..else конструкции. Следующий код не скопилируется, даже если вызвать сint
типом. Компилятор в любов случае фэйлится наstatic_assert
.Мое предложение - не проверять
static_assert
в терминальном случае. Достоинства:else
веткой.throw
.Полезные ссылки: