8 Expressions [expr]

8.2 Postfix expressions [expr.post]

8.2.5 Class member access [expr.ref]

Постфиксное выражение, за которым следует точка . или стрелка ->, необязательно, за которым следует ключевое слово template ([temp.names]), а затем следует за ним id-expression, является постфиксным выражением. Выражение постфикса перед точкой или стрелкой оценивается;67 результат этой оценки, вместе с id-expression, определяет результат всего постфиксного выражения.

Для первого варианта (точка) первым выражением должно быть значение glvalue, имеющее полный тип класса. Для второго варианта (стрелка) первое выражение должно быть prvalue, имеющим указатель на полный тип класса. Выражение E1->E2 преобразуется в эквивалентную форму (*(E1)).E2; остальная часть [expr.ref] будет адресована только первому варианту (точка).68 В любом случае он id-expressionдолжен называть члена класса или одного из его базовых классов. [ Note: Поскольку имя класса вставлено в его область действия класса (пункт [class]), имя класса также считается вложенным членом этого класса. ] [ Описывает , как имена ищутся после того , как и операторов. ]end noteNote: [basic.lookup.classref] . -> end note

Сокращение как , называется . Если это битовое поле, то это битовое поле. Тип и ценностная категория определяются следующим образом. В оставшейся части , представляет собой либо или отсутствие , и представляет собой либо или отсутствие . представляет произвольный набор cv-квалификаторов, как определено в .postfix-expression.id-expression E1.E2E1 object expression E2 E1.E2 E1.E2 [expr.ref] cq const const vq volatile volatile cv [basic.type.qualifier]

Если E2 объявлен тип «ссылка на T», то E1.E2 это lvalue; тип E1.E2 есть T. В противном случае применяется одно из следующих правил.

  • Если E2 является членом статических данных и типа E2 IS T, то E1.E2 есть именующий; выражение обозначает названный член класса. Тип E1.E2 есть T.

  • Если E2 это нестатический член данных, тип E1 - «cq1 vq1 X», а тип E2 - «cq2 vq2 T», выражение обозначает именованный член объекта, обозначенного первым выражением. Если E1 - lvalue, то E1.E2 это lvalue; в противном случае E1.E2 - значение x. Пусть это обозначение vq12 означает «объединение» vq1 и vq2; то есть если vq1 или vq2 есть volatile, то vq12 есть volatile. Точно так же пусть обозначение cq12 означает «объединение» cq1 и cq2; то есть если cq1 или cq2 есть const, то cq12 есть const. Если E2 объявлен mutable членом, то тип E1.E2 - «vq12 T». Если E2 не объявлен mutable членом, то тип E1.E2 - «cq12 vq12 T».

  • Если E2 это (возможно, перегруженная) функция-член, функция overload resolution используется для определения того,E1.E2 относится ли она к статической или нестатической функции-члену.

    • Если он относится к статической функции-члену и типом E2 является «функция возврата списка типов-параметров T», то E1.E2 это lvalue; выражение обозначает статическую функцию-член. Тип того E1.E2 же типа, что и E2, а именно «функция возврата списка типов параметров T».

    • В противном случае, если E1.E2 относится к нестатической функции-члену и типом E2 является «функция возврата списка типов-параметров », то это prvalue. Выражение обозначает нестатическую функцию-член. Выражение может использоваться только как левый операнд вызова функции-члена ( ). [ Любой лишний набор круглых скобок, окружающий выражение, игнорируется ( ). ] Тип - «функция возврата списка типов параметров ». cv ref-qualifieropt TE1.E2 [class.mfct]Note: [expr.prim] end note E1.E2 cv T

  • Если E2 это вложенный тип, выражение E1.E2 имеет неправильный формат.

  • Если E2 является перечислителем членов и типом E2 является T, выражение E1.E2 является значением prvalue. Тип E1.E2 есть T.

Если E2 это нестатический член данных или нестатическая функция-член, программа плохо сформирована, если класс, который E2 является непосредственно членом, является неоднозначным base ([class.member.lookup]) класса именования ([class.access.base]) из E2. [ Note: Программа также плохо сформирована, если класс именования является неоднозначным основанием типа класса выражения объекта; см [class.access.base]. ]end note

Если вычисляется выражение доступа к члену класса, оценка подвыражения происходит, даже если результат не нужен для определения значения всего постфиксного выражения, например, если id-expressionобозначает статический член.

Обратите внимание, что (*(E1)) это lvalue.