cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

static_assert в constexpr функции #563

Closed blacktea closed 1 year ago

blacktea commented 1 year ago

Мотивация

В 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 в терминальном случае. Достоинства:

Полезные ссылки:

apolukhin commented 1 year ago

Приняли в C++23 https://github.com/cplusplus/papers/issues/1251