Введение
constexpr
не был представлен как способ сказать реализации, что что-то может быть оценено в контексте, который требует константного выражения ; Соответствующие реализации смогли доказать это до C ++ 11.
То, что реализация не может доказать, является намерением определенного фрагмента кода:
- Что разработчик хочет выразить этой сущностью?
- Должны ли мы слепо допустить использование кода в константном выражении только потому, что это работает?
Чего бы не было в мире constexpr
?
Допустим, вы разрабатываете библиотеку и понимаете, что хотите вычислить сумму каждого целого числа в интервале (0,N]
.
int f (int n) {
return n > 0 ? n + f (n-1) : n;
}
Отсутствие намерения
Компилятор может легко доказать, что вышеуказанная функция вызывается в константном выражении, если переданный аргумент известен во время перевода; но вы не объявили это намерением - так уж случилось.
Теперь приходит кто-то другой, читает вашу функцию, выполняет тот же анализ, что и компилятор; « О, эту функцию можно использовать в постоянном выражении!» и пишет следующий фрагмент кода.
T arr[f(10)]; // freakin' magic
Оптимизация
Вы, как «замечательный» разработчик библиотек, решаете, что f
следует кешировать результат при вызове; кто хотел бы рассчитывать один и тот же набор значений снова и снова?
int func (int n) {
static std::map<int, int> _cached;
if (_cached.find (n) == _cached.end ())
_cached[n] = n > 0 ? n + func (n-1) : n;
return _cached[n];
}
Результат
Внедрив свою глупую оптимизацию, вы просто прервали каждое использование своей функции в контексте, где требовалось постоянное выражение .
Вы никогда не обещали, что функция будет использоваться в постоянном выражении , и без этого constexpr
не было бы способа обеспечить такое обещание.
Итак, зачем нам это constexpr
?
Основное использование constexpr - объявить намерение .
Если объект не помечен как constexpr
- он никогда не предназначался для использования в константном выражении ; и даже если это так, мы полагаемся на компилятор для диагностики такого контекста (потому что он игнорирует наши намерения).
constexpr
? Если так, я могу видеть использование.