Я не понимаю, что [dcl.enum] / 4 говорит в отношении «спецификатора enum», выделенного ниже - PullRequest
1 голос
/ 11 марта 2019

[dcl.emum] / 4

Если enum-head-name содержит вложенное имя-спецификатор , оно не должно начинаться с спецификатора decltype и , включающего спецификатор перечисления или opaque-enum-объявление должно ссылаться на перечисление, которое было ранее объявленный непосредственно в классе или пространстве имен, к которому относится ссылка на nested-name-спецификатор или в элементе встроенного пространства имен набор ([namespace.def]) этого пространства имен (т. е. ни наследуемый, ни вводится с помощью объявления-использования), а спецификатор enum или opaque-enum-объявление должно появиться в пространстве имен, включающем предыдущая декларация.

Я полагаю, что этот абзац как-то связан с простым фрагментом ниже. Но я не могу понять, что это за спецификатор перечисления , упомянутый выше. Обратите внимание, что оба S::E::i и S::i ниже enum-head-name s, но эти два выражения не содержат enum-спецификатор s!

#include <iostream>
struct S
{
    enum E { i = 1 };
};

int main(){
    std::cout << S::E::i << '\n'; 
    std::cout << S::i << '\n';
}

Этот код печатает

1
1

1 Ответ

3 голосов
/ 11 марта 2019

Я считаю, что этот абзац как-то связан с простым фрагментом ниже.

Он не связан с этим фрагментом, поскольку спецификатор enum enum E { i = 1 } не содержит спецификатора вложенного имени.

Обратите внимание, что S::E::i и S::i ниже являются именами-перечислениями

Это не имена enum-head. enum-head-names находятся только внутри enum-head, которые находятся только внутри enum-спецификаторов. Это просто квалифицированные идентификаторы, которые состоят из спецификатора вложенного имени и идентификатора, присваивающего имя перечислителю.

Пример спецификатора перечисления, у которого enum-head-name действительно есть спецификатор вложенного имени, и к которому применяется указанное в кавычках правило:

    struct S
    {
        enum E : int;
//      ^^^^^^^^^^^^          opaque-enum-declaration
    };
    enum S::E : int { i = 1 };
//       ^^^                  nested-name-specifier
//       ^^^^                 enum-head-name
//  ^^^^^^^^^^^^^^^           enum-head
//  ^^^^^^^^^^^^^^^^^^^^^^^^^ enum-specifier
...