Namespaces
Variants

Elaborated type specifier

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

정교화된 타입 지정자는 이전에 선언된 클래스 이름(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
1) 클래스 타입에 대한 정교화된 타입 지정자.
2) 열거형 타입에 대한 정교화된 타입 지정자.
3) elaborated type specifier만으로 구성된 선언은 항상 해당 선언을 포함하는 scope 내에서 identifier 로 명명된 클래스 타입을 선언합니다.

불투명 열거형 선언 은 형식 (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 키워드는 (범위가 지정되었든 아니든) 열거형 타입 을 참조할 때 반드시 사용해야 합니다.
  • union class-key union 을 참조할 때 반드시 사용해야 합니다.
  • class 또는 struct class-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 를 가진 이름 없는 상수 매개변수가 아닙니다.

키워드

class , struct , union , enum

참고문헌

  • 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]