C ++ определение интегральной константы - PullRequest
3 голосов
/ 05 июня 2019

В текущем стандарте C ++ есть следующий абзац ( expr.const # 5 ) (выделено мной):

Выражение целочисленной константы - это выражение типа перечисления целого или незаданного типа, неявно преобразуемое в значение , где преобразованное выражение - это выражение основной константы. [Примечание: такие выражения могут использоваться как длины битовых полей, как инициализаторы перечислителя, если базовый тип не является фиксированным ([dcl.enum]), и как выравнивания. - конец примечания]

У меня есть два вопроса относительно этого определения:

  1. Означает ли фраза «неявно преобразуемый в prvalue», что для выражения, которое следует считать «интегральным константным выражением», оно должно появляться в контексте, который заставляет его неявно преобразовывать в prvalue?

  2. Что означает «преобразованное выражение»? Я знаю, что этот вопрос рассматривается в Разъяснение определения преобразованного константного выражения . Ответ на этот вопрос таков: «преобразованное выражение» - t после следующей инициализации: T t = expr;. Однако я не вижу, как оценка этого выражения (t) соответствовала бы какому-либо из правил, приведенных в [expr.const # 4] (параграфе, описывающем необходимые условия для выражения, чтобы оно считалось основным константным выражением ) что делает его неквалифицированным как ядро-константа .

Спасибо.

Ответы [ 2 ]

1 голос
/ 09 июня 2019

Я посмотрел на исходный код clang, в частности на функцию " CheckConvertedConstantExpression " внутри "SemaOverload.cpp". Здесь выполняются следующие операции:

  1. найти требуемую неявную последовательность преобразования
  2. проверьте, используются ли только преобразования, перечисленные в http://eel.is/c++draft/expr.const#7
  3. выполнить неявное преобразование (на этом этапе я считаю, что создается новое выражение, например, если исходное выражение f() относится к типу класса A с пользовательской функцией преобразования в int, и контекст требует int, тогда новое выражение должно быть f().operator int())
  4. проверить, требуются ли какие-либо сужающие преобразования
  5. оценивает выражение, сгенерированное на шаге 3 (который неявно проверяет, является ли оно constant expression)

Поэтому я считаю, что, как указано в answer @Davis Herring, термин «преобразованное выражение» означает новое выражение, оценка которого включает в себя как оценку исходного выражения, как написано в программе, так и оценка любого необходимого преобразования.

1 голос
/ 05 июня 2019

Утверждение, что целочисленное константное выражение является , неявно преобразуемым в значение prvalue, означает, что преобразование lvalue-to-rvalue применяется к любому выражению, используемому в качестве выражения интегральной константы. В одном случае, когда выражение может быть целочисленным константным выражением - инициализировать нелокальный объект целочисленного типа с константным типом, который может использоваться в константных выражениях - инициализатор в любом случае является предварительным значением, поэтому никаких изменений интерпретации может иметь место.

Кроме того, оба ваших вопроса имеют один и тот же ответ: любые преобразования, необходимые для приведения выражения (как написано) к целочисленному типу prvalue, также должны быть разрешены в выражении основной константы (см., Например, /4.7 непосредственно перед вашей цитатой и / 6 сразу после нее). «Преобразованное выражение» включает преобразование в интерпретации T t=e;, а не только в id-выражение t (которое, например, всегда будет lvalue).

...