Elaborated type specifier
정교화된 타입 지정자는 이전에 선언된 클래스 이름(class, struct, union)이나 이전에 선언된 enum 이름을 참조하는 데 사용될 수 있으며, 해당 이름이 비타입 선언에 의해 가려진 경우 에도 가능합니다. 또한 새로운 클래스 이름을 선언하는 데에도 사용될 수 있습니다.
목차 |
구문
| class-key class-name | (1) | ||||||||
enum
enum-name
|
(2) | ||||||||
class-key
attr
(선택적)
identifier
;
|
(3) | ||||||||
| class-key | - | 다음 중 하나 class , struct , union |
| class-name | - | 이전에 선언된 클래스 타입의 이름(선택적으로 한정됨 ) 또는 이전에 타입 이름으로 선언되지 않은 식별자 |
| enum-name | - | 이전에 선언된 열거형 타입의 이름(선택적으로 한정됨 ) |
| attr | - | (C++11부터) 임의의 수의 attributes |
불투명 열거형 선언 은 형식 (3) 과 유사하지만, 불투명 열거형 선언 이후에는 열거형 타입이 완전한 타입이 됩니다.
설명
형식 (3) 은 정교화된 타입 지정자(elaborated type specifier)의 특별한 경우로, 일반적으로 클래스의 전방 선언(forward declaration) 이라고 합니다. 형식 (3) 에 대한 설명은 Forward declaration 을 참조하십시오. 다음 내용은 형식 (1) 과 (2) 에만 적용됩니다.
elaborated type 지정자 내의 class-name 또는 enum-name 은 단순 식별자일 수도 있고 qualified-id 일 수도 있습니다. 해당 이름은 그 형태에 따라 unqualified name lookup 또는 qualified name lookup 을 사용하여 조회됩니다. 그러나 어느 경우든, non-type 이름은 고려되지 않습니다.
class T { public: class U; private: int U; }; int main() { int T; T t; // 오류: 지역 변수 T가 발견됨 class T t; // OK: ::T를 찾음, 지역 변수 T는 무시됨 T::U* u; // 오류: T::U 조회 시 private 데이터 멤버를 찾음 class T::U* u; // OK: 데이터 멤버는 무시됨 }
이름 조회가 이전에 선언된 타입 이름을 찾지 못하고, elaborated-type-specifier가
class
,
struct
, 또는
union
(즉,
enum
이 아닌)으로 시작하고,
class-name
이 한정되지 않은 식별자인 경우, elaborated-type-specifier는 class-name의 클래스 선언이며 대상 범위는 가장 가까운 둘러싸는 네임스페이스 또는 블록 범위입니다.
template<typename T> struct Node { struct Node* Next; // OK: Node 조회가 주입된 클래스 이름을 찾음 struct Data* Data; // OK: 전역 범위에서 Data 타입을 선언하고 // 데이터 멤버 Data도 선언함 friend class ::List; // 오류: 한정된 이름을 도입할 수 없음 enum Kind* kind; // 오류: enum을 도입할 수 없음 }; Data* p; // OK: struct Data가 선언됨
이름이 typedef 이름 , 타입 별칭 , 템플릿 타입 매개변수 , 또는 별칭 템플릿 특수화 를 참조하는 경우, 프로그램은 형식에 맞지 않습니다. 그렇지 않으면, 정교한 타입 지정자는 단순 타입 지정자 가 자신의 타입 이름을 도입하는 것과 같은 방식으로 선언에 이름을 도입합니다.
template<typename T> class Node { friend class T; // 오류: 타입 매개변수는 정교화된 타입 지정자에 나타날 수 없음; // 참고: 유사한 선언 `friend T;`는 정상적으로 동작함. }; class A {}; enum b { f, t }; int main() { class A a; // 정상: 'A a;'와 동등함 enum b flag; // 정상: 'b flag;'와 동등함 }
elaborated-type-specifier에 있는 이름이 참조하는 선언과 종류가 일치하려면
class-key
또는
enum
키워드가 존재해야 합니다.
-
enum키워드는 (범위가 지정되었든 아니든) 열거형 타입 을 참조할 때 반드시 사용해야 합니다. -
unionclass-key 는 union 을 참조할 때 반드시 사용해야 합니다. -
class또는structclass-key 중 하나는 비-union 클래스 타입을 참조할 때 반드시 사용해야 합니다 (여기서class과struct키워드는 서로 교환 가능합니다).
enum class E { a, b }; enum E x = E::a; // 정상 enum class E y = E::b; // 오류: 'enum class'는 정교화된 타입 지정자를 도입할 수 없음 struct A {}; class A a; // 정상
템플릿 인자
로 사용될 때,
class
T
는 이름이
T
인 타입 템플릿 매개변수이며, 상세 타입 지정자로 도입된 타입
T
를 가진 이름 없는 상수 매개변수가 아닙니다.
키워드
참고문헌
- C++23 표준 (ISO/IEC 14882:2024):
-
- 6.5.6 정교화된 타입 지정자 [basic.lookup.elab]
-
- 9.2.9.4 정교화된 타입 지정자 [dcl.type.elab]
- C++20 표준 (ISO/IEC 14882:2020):
-
- 6.5.4 정교화된 타입 지정자 [basic.lookup.elab]
-
- 9.2.8.3 정교화된 타입 지정자 [dcl.type.elab]
- C++17 표준 (ISO/IEC 14882:2017):
-
- 6.4.4 정교화된 타입 지정자 [basic.lookup.elab]
-
- 10.1.7.3 정교화된 타입 지정자 [dcl.type.elab]
- C++14 표준(ISO/IEC 14882:2014):
-
- 3.4.4 정교화된 타입 지정자 [basic.lookup.elab]
-
- 7.1.6.3 정교화된 타입 지정자 [dcl.type.elab]
- C++11 표준 (ISO/IEC 14882:2011):
-
- 3.4.4 정교화된 타입 지정자 [basic.lookup.elab]
-
- 7.1.6.3 정교화된 타입 지정자 [dcl.type.elab]
- C++98 표준(ISO/IEC 14882:1998):
-
- 3.4.4 정교화된 타입 지정자 [basic.lookup.elab]
-
- 7.1.5.3 정교화된 타입 지정자 [dcl.type.elab]
|
이 섹션은 불완전합니다
이유: 아마도 cpp/language/class에서 9.1[class.name]/2-3의 대부분을 추출해야 함 |