Введение
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
- он никогда не предназначался для использования в константном выражении ;и даже если это так, мы полагаемся на компилятор для диагностики такого контекста (потому что он игнорирует наши намерения).