constexpr
Ключевое слово было введено в C ++ 11, так как (я думаю) была соответствующая идея «константных выражений». Тем не менее, эта концепция неявно присутствовала в C ++ 98 / c ++ 03, поскольку объявления массивов требуют постоянного выражения:
// valid:
int a[sizeof(int)];
int b[3+7];
int c[13/4];
const int n = 3;
int d[n];
// invalid:
int m = 4;
int e[m];
Существуют и другие «константные выражения», то есть выражения, которые могут (и / или должны) оцениваться во время компиляции; Одним из примеров являются аргументы шаблона.
Для pre-C ++ 11, существует ли следующее, в стандартах C ++ 98/03 или где-либо еще?
constexpr а также константные выражения связаны в том, что constexpr говорит нам, что переменная или функция может быть использована там, где постоянное выражение может быть использован. Вот что говорит нам cppreference:
Спецификатор constexpr заявляет, что можно оценить
значение функции или переменной во время компиляции. Такие переменные и
функции могут быть использованы там, где только постоянная времени компиляции
выражения допускаются.
Постоянные выражения присутствовали до C ++ 11, и правила, регулирующие константные выражения до C ++ 11, рассматриваются в том же месте в Проект стандарта C ++ 03(это самый ранний публичный проект, доступный ближе всего к C ++ 03)1 как проект стандарта C ++ 11 какой раздел 5.19
Постоянные выражения, У cppreference есть хорошее резюме по этой теме в Постоянные выражения страница, но она ориентирована на C ++ 11 и C ++ 14, и трудно сказать, что применяется до C ++ 11.
Стандарт до C ++ 11 перечисляет, где требуется постоянное выражение, в первом абзаце 5.19
и выглядит завершенным:
В некоторых местах C ++ требует выражений, которые оценивают
интеграл или константа перечисления: как границы массива (8.3.4,
5.3.4) как выражения случая (6.4.2), как длины битовых полей (9.6), как инициализаторы перечислителя (7.2), как инициализаторы статического члена (9.4.2),
и как целочисленные или перечислительные нетиповые аргументы шаблона (14.3).
остальная часть абзаца 1 говорит:
Интегральная константа-выражение может включать только литералы
арифметические типы (2.13, 3.9.1), перечислители, энергонезависимые константы
переменные или статические члены данных целочисленных или перечислимых типов
инициализируется с помощью константных выражений (8.5), не тип шаблона
параметры целочисленных или перечислимых типов и размер выражений.
Плавающие литералы (2.13.3) могут появляться, только если они приведены к
целочисленные или перечислимые типы. Только преобразования типа в целое или
Типы перечисления могут быть использованы. В частности, кроме размера
выражения, функции, объекты класса, указатели или ссылки должны
не должны использоваться, а присваивание, увеличение, уменьшение, вызов функции или
Запятые не должны использоваться.
и сопровождается 5
больше параграфов, которые перечисляют дополнительные требования.
В C ++ 11 есть список, где константные выражения могут быть использованы в абзаце 3 но это не проясняет, где они требуются. Вы, вероятно, должны искать термин постоянное выражение чтобы найти все места, где это требуется, и обычно будет фраза, похожая на:
должно быть постоянным выражением
должен будучи важным термином с момента нарушения должен требование делает программу плохо сформированной.
В качестве альтернативы вы можете использовать Annex A
Грамматическое краткое содержание и искать константа-выражение и это должно охватывать все места в грамматике, где постоянное выражение требуется, например:
enumerator = constant-expression
Сноска:
2005
, Более ранние версии требуют аутентификации. Насколько я знаю раздел 5.19
не сильно изменился.