"Константные выражения" до С++ 11

Ключевое слово constexpr было введено в С++ 11, поскольку (я думаю) была соответствующей идеей "постоянных выражений". Однако эта концепция неявно присутствует в С++ 98/С++ 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-С++ 11 существует ли следующее: либо в стандартах С++ 98/03, либо в другом месте?

  • Полный список синтаксических конструкций, требующих постоянных выражений (например, объявления массивов и экземпляры шаблонов)
  • Правила, регулирующие такие постоянные выражения (предположительно это будет просто отображение из элементов в приведенном выше списке их определений в стандарте)

Ответы

Ответ 1

constexpr, а константные выражения связаны с тем, что constexpr сообщает нам, что переменная или функция могут использоваться там, где константное выражение может быть используемый. Об этом говорит cppreference:

Спецификатор constexpr заявляет, что можно оценить значение функции или переменной во время компиляции. Такие переменные и функции можно использовать тогда, когда только константа времени компиляции выражения разрешены.

Константы expresions присутствовали до С++ 11, а правила, определяющие константные выражения pre С++ 11, рассматриваются в том же месте в С++ 03 проект стандарта (это самый ранний публичный проект, доступный ближе всего к С++ 03) 1 в качестве draft С++ 11 standard, который является разделом 5.19 Константные выражения, cppreference имеет хорошее резюме по этой теме в странице констант, но он ориентирован на С++ 11 и С++ 14, и трудно сказать, что применяет pre С++ 11.

В стандартном pre С++ 11 перечислены, где требуется постоянное выражение, в первом абзаце 5.19 и он выглядит полным:

В нескольких местах С++ требует выражений, которые интегральная или континуальная константа: как границы массива (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 больше абзацев, в которых перечислены дополнительные требования.

В С++ 11 есть список, где константные выражения могут использоваться в параграфе 3, но не уточняет, где они требуются. Вам, вероятно, придется искать выражение константы term, чтобы найти все места, где это требуется, и обычно будет фраза, похожая на:

должно быть постоянным выражением

Важным термином, поскольку нарушение требования a делает программу плохо сформированной.

В качестве альтернативы вы можете использовать Annex A резюме грамматики и искать константное выражение, которое должно охватывать все места в грамматике, где требуется постоянное выражение, например:

enumerator = constant-expression

Сноска:

  • Этот ответ: Где найти текущие стандартные документы C или С++? содержит полный список проектов стандартов. К сожалению, наиболее близким, доступным для общественности, является ранний 2005. Для более ранних версий требуется аутентификация. Насколько я знаю, раздел 5.19 не сильно изменился.