Type
객체 , 참조 , 함수 (여기에는 함수 템플릿 특수화 를 포함함), 그리고 표현식 은 타입 이라는 속성을 가지며, 이는 해당 개체들에 허용되는 연산을 제한함과 동시에 일반적인 비트 시퀀스에 의미론적 의미를 부여합니다.
목차 |
타입 분류
C++ 타입 시스템은 다음의 타입들로 구성됩니다:
- 기본 타입 (참고: std::is_fundamental ):
-
- 타입 void (참조: std::is_void );
|
(C++11부터) |
-
- 산술 타입(참조: std::is_arithmetic ):
-
- 정수 타입(포함 cv-qualified versions , 참조: std::is_integral , integral type의 동의어는 integer type):
-
- 타입 bool ;
- 문자 타입:
-
- 좁은 문자 타입:
-
- 일반 문자 타입: char , signed char , unsigned char [1]
|
(C++20부터) |
-
-
-
-
- 와이드 문자 타입: char16_t , char32_t , (C++11부터) wchar_t ;
- 부호 있는 정수 타입:
-
- 표준 부호 있는 정수 타입: signed char , short , int , long , long long ;
-
-
-
|
(C++11부터) |
-
-
-
- 부호 없는 정수 타입:
-
- 표준 부호 없는 정수 타입: unsigned char , unsigned short , unsigned , unsigned long , unsigned long long ;
-
-
|
(C++11부터) |
-
-
- 부동소수점 타입 (참조: std::is_floating_point ):
-
- 표준 부동소수점 타입: float , double , long double 및 이들의 cv-qualified versions ;
-
|
(C++23부터) |
- 복합 타입 (참고: std::is_compound ):
-
- 참조 타입 (참고: std::is_reference ):
-
- lvalue 참조 타입 (참고: std::is_lvalue_reference ):
-
- 객체 타입에 대한 lvalue 참조;
- 함수 타입에 대한 lvalue 참조;
|
(C++11부터) |
-
- 포인터 타입 (참조: std::is_pointer ):
- 멤버 포인터 타입 (참조: std::is_member_pointer ):
-
- 데이터 멤버 포인터 타입 (참조: std::is_member_object_pointer );
- 멤버 함수 포인터 타입 (참조: std::is_member_function_pointer );
- 배열 타입 (참조: std::is_array );
- 함수 타입 (참조: std::is_function );
- 열거형 타입 (참조: std::is_enum );
|
(C++11부터) |
-
-
- non-union types (참고: std::is_class );
- union types (참고: std::is_union ).
-
- ↑ signed char 와 unsigned char 는 narrow character 타입이지만, character 타입은 아닙니다. 다시 말해, narrow character 타입들의 집합은 character 타입들의 집합의 부분집합이 아닙니다.
참조와 함수를 제외한 모든 비-cv-한정 타입에 대해, 타입 시스템은 해당 타입의 세 가지 추가 cv-한정 버전 을 지원합니다 ( const , volatile , 그리고 const volatile ).
기타 카테고리
객체 타입 (참고: std::is_object )은 함수 타입도, 참조 타입도, (cv 한정자가 있을 수 있는) void 도 아닌 (cv 한정자가 있을 수 있는) 타입입니다.
다음 타입들을 통칭하여 스칼라 타입 이라고 합니다 (참고: std::is_scalar ):
| (C++11 이후) |
- 이러한 타입들의 cv-qualified 버전
다음 유형들을 총칭하여 암시적 수명 유형(implicit-lifetime types) 라고 합니다:
- 스칼라 타입
- 암시적 수명 클래스 타입
- 배열 타입
- 이러한 타입들의 CV 한정 버전
|
다음 유형들을 총칭하여 trivially copyable types (사소하게 복사 가능한 타입)이라고 합니다:
다음 유형들을 총칭하여 standard-layout types (표준 레이아웃 타입)이라고 합니다:
|
(C++11부터) |
| 타입 트레이트 계층 구조 다이어그램 |
|---|
|
참고: SVG 이미지의 요소들은 클릭 가능하지만, 먼저 새 브라우저 탭에서 다이어그램을 열어야 합니다 |
사용 중단된 카테고리
|
다음 유형들을 통칭하여 POD 타입 이라고 합니다 (참조: std::is_pod ):
|
(C++20에서 사용 중단됨) |
|
다음 유형들을 통칭하여 trivial 타입 이라고 합니다 (참조: std::is_trivial ):
|
(C++11부터)
(C++26에서 사용 중단됨) |
프로그램 정의 타입
프로그램 정의 특수화 는 C++ 표준 라이브러리 의 일부가 아니며 구현에 의해 정의되지 않은 명시적 특수화 또는 부분 특수화 입니다.
프로그램 정의 타입 은 다음 유형 중 하나입니다:
- C++ 표준 라이브러리에 포함되지 않고 구현에 의해 정의되지 않은 non- closure (since C++11) class type 또는 enumeration type
|
(since C++11) |
- 프로그램 정의 특수화의 인스턴스화 .
타입 명명
name 은 다음 방법을 통해 타입을 참조하도록 선언될 수 있습니다:
- class 선언;
- union 선언;
- enum 선언;
- typedef 선언;
- type alias 선언.
이름이 없는 타입들은 C++ 프로그램에서 종종 참조될 필요가 있습니다; 이를 위한 구문은
type-id
로 알려져 있습니다. 타입
T
를 명명하는 type-id의 구문은
선언
문법에서 식별자가 생략된 타입
T
의 변수나 함수 선언의 구문과 정확히 동일하지만, 선언 문법의
decl-specifier-seq
가
type-specifier-seq
로 제한되며, 새로운 타입들은 type-id가 비템플릿 타입 별칭 선언의 우변에 나타날 때만 정의될 수 있다는 점이 다릅니다.
int* p; // int에 대한 포인터 선언 static_cast<int*>(p); // type-id는 "int*" int a[3]; // 3개의 int 배열 선언 new int[3]; // type-id는 "int[3]" (new-type-id라고 함) int (*(*x[2])())[3]; // 3개의 int 배열에 대한 포인터를 반환하는 함수에 대한 // 2개의 포인터 배열 선언 new (int (*(*[2])())[3]); // type-id는 "int (*(*[2])())[3]" void f(int); // int를 받고 void를 반환하는 함수 선언 std::function<void(int)> x = f; // 타입 템플릿 매개변수는 type-id "void(int)" std::function<auto(int) -> void> y = f; // 동일 std::vector<int> v; // int 벡터 선언 sizeof(std::vector<int>); // type-id는 "std::vector<int>" struct { int x; } b; // 새로운 타입을 생성하고 해당 타입의 객체 b를 선언 sizeof(struct { int x; }); // 오류: sizeof 표현식에서 새로운 타입을 정의할 수 없음 using t = struct { int x; }; // 새로운 타입을 생성하고 t를 해당 타입의 별칭으로 선언 sizeof(static int); // 오류: 저장 클래스 지정자가 type-specifier-seq의 일부가 아님 std::function<inline void(int)> f; // 오류: 함수 지정자도 허용되지 않음
선언 문법에서 이름이 제거된 declarator 부분을 abstract-declarator 라고 부릅니다.
타입 식별자는 다음과 같은 상황에서 사용될 수 있습니다:
- 캐스트 표현식 에서 대상 타입을 지정할 때;
-
sizeof,alignof,alignas,new, 그리고typeid의 인자로 사용될 때; - 타입 별칭 선언의 우측에 사용될 때;
- 함수 선언의 후행 반환 타입으로 사용될 때;
- 템플릿 타입 매개변수 의 기본 인자로 사용될 때;
- 템플릿 타입 매개변수 에 대한 템플릿 인자로 사용될 때;
|
(C++17까지) |
타입 식별자는 다음과 같은 상황에서 일부 수정과 함께 사용될 수 있습니다:
- 함수의 매개변수 목록 에서 (매개변수 이름이 생략된 경우), type-id는 type-specifier-seq 대신 decl-specifier-seq 을 사용합니다 (특히, 일부 storage class specifiers가 허용됨);
- 사용자 정의 변환 함수 의 이름에서, abstract declarator는 함수 또는 배열 연산자를 포함할 수 없습니다.
|
이 섹션은 불완전합니다
이유: 8.2[dcl.ambig.res]를 간결하게 요약할 수 있는 경우 |
|
이 섹션은 불완전합니다
이유: decltype과 auto에 대한 언급 및 링크 필요 |
정규화된 타입 지정자
정교화된 타입 지정자는 이전에 선언된 클래스 이름(class, struct, union)이나 이전에 선언된 enum 이름을 참조하는 데 사용될 수 있으며, 해당 이름이 비타입 선언에 의해 가려진 경우에도 가능합니다. 또한 새로운 클래스 이름을 선언하는 데에도 사용될 수 있습니다.
자세한 내용은 elaborated type specifier 를 참조하십시오.
정적 타입
프로그램의 컴파일 타임 분석 결과로 얻어지는 표현식의 타입은 해당 표현식의 static type 으로 알려져 있습니다. static type은 프로그램 실행 중에 변경되지 않습니다.
동적 타입
어떤 glvalue 표현식 이 다형성 객체 를 참조하는 경우, 해당 객체의 가장 파생된 객체의 타입을 동적 타입이라고 합니다.
// 주어진 조건 struct B { virtual ~B() {} }; // 다형성 타입 struct D : B {}; // 다형성 타입 D d; // 최종 파생 객체 B* ptr = &d; // (*ptr)의 정적 타입은 B // (*ptr)의 동적 타입은 D
prvalue 표현식의 경우, 동적 타입은 항상 정적 타입과 동일합니다.
불완전 타입
다음 타입들은 불완전 타입 입니다:
- 타입 void (가능하게 cv -qualified);
-
불완전하게 정의된 객체 타입들
:
- 선언되었지만 정의되지 않은 클래스 타입 (예: forward declaration 에 의해);
- unknown bound 배열 ;
- 불완전한 타입의 요소들로 이루어진 배열;
- enumeration type 선언 지점부터 그 underlying type이 결정될 때까지.
다른 모든 타입은 완전합니다.
다음 중 어느 하나의 상황에서도 타입
T
가 완전해야 합니다:
-
반환 타입이
T이거나 인수 타입이T인 함수의 정의 또는 호출; -
타입
T의 객체 정의 ; -
타입
T의 비정적 클래스 데이터 멤버 선언; -
타입
T의 객체 또는 요소 타입이T인 배열에 대한new표현식 ; -
타입
T의 glvalue에 적용된 lvalue-to-rvalue 변환 ; -
타입
T로의 암시적 또는 명시적 변환; -
타입
T
*
또는
T
&
로의
표준 변환
,
dynamic_cast, 또는static_cast(단, 널 포인터 상수 에서의 변환이나 cv-한정 가능한 void 포인터 에서의 변환은 제외); -
타입
T의 표현식에 적용된 클래스 멤버 접근 연산자 ; -
타입
T에 적용된typeid,sizeof, 또는alignof연산자; -
T포인터에 적용된 산술 연산자 ; -
기본 클래스가
T인 클래스 정의; -
타입
T의 lvalue에 대한 할당; -
타입
T, T & , 또는 T * 의 핸들러 .
(일반적으로,
T
의 크기와 레이아웃을 알아야 할 때.)
이러한 상황 중 하나라도 번역 단위에서 발생하는 경우, 해당 타입의 정의는 동일한 번역 단위에 나타나야 합니다. 그렇지 않으면 필수적이지 않습니다.
불완전하게 정의된 객체 타입은 완료될 수 있습니다:
- 클래스 타입(예: class X )은 번역 단위의 한 지점에서는 불완전한 타입으로 간주될 수 있고, 나중에 완전한 타입으로 간주될 수 있습니다; class X 타입은 두 지점에서 동일한 타입입니다:
struct X; // X의 선언, 아직 정의는 제공되지 않음 extern X* xp; // xp는 불완전 타입에 대한 포인터: // X의 정의에 접근할 수 없음 void foo() { xp++; // 잘못된 형식: X가 불완전함 } struct X { int i; }; // X의 정의 X x; // OK: X의 정의에 접근 가능 void bar() { xp = &x; // OK: 타입은 "X에 대한 포인터" xp++; // OK: X가 완전함 }
- 배열 객체의 선언된 타입은 불완전한 클래스 타입의 배열일 수 있으며 따라서 불완전할 수 있습니다; 클래스 타입이 번역 단위에서 나중에 완성되면 배열 타입은 완전해집니다; 이 두 지점에서의 배열 타입은 동일한 타입입니다.
-
배열 객체의 선언된 타입은 알려지지 않은 경계의 배열일 수 있으며 따라서 번역 단위의 한 지점에서는 불완전하고 나중에 완전해질 수 있습니다; 이 두 지점에서의 배열 타입("
T의 알려지지 않은 경계 배열"과 " NT배열")은 서로 다른 타입입니다.
알 수 없는 경계를 가진 배열에 대한 포인터나 참조의 유형은 영구적으로 불완전한 유형을 가리키거나 참조합니다.
typedef
선언으로 명명된 알 수 없는 경계의 배열은 영구적으로 불완전한 유형을 참조합니다. 두 경우 모두 배열 유형을 완성할 수 없습니다:
extern int arr[]; // arr의 타입은 불완전함 typedef int UNKA[]; // UNKA는 불완전한 타입 UNKA* arrp; // arrp는 불완전한 타입에 대한 포인터 UNKA** arrpp; void foo() { arrp++; // 오류: UNKA는 불완전한 타입 arrpp++; // OK: UNKA*의 크기는 알려짐 } int arr[10]; // 이제 arr의 타입은 완전함 void bar() { arrp = &arr; // OK: 자격 변환 (C++20부터) arrp++; // 오류: UNKA는 완성될 수 없음 }
결함 보고서
다음 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 328 | C++98 |
클래스 타입의 객체가 생성되지 않았다면
불완전한 타입의 클래스 멤버가 금지되지 않았음 |
비정적 클래스 데이터 멤버는
완전한 타입이어야 함 |
| CWG 977 | C++98 |
열거형 타입이 정의 내에서 완전한 타입이 되는
시점이 불분명했음 |
기본 타입이 결정되면
해당 타입은 완전한 타입이 됨 |
| CWG 1362 | C++98 |
T*
또는
T&
타입으로의 사용자 정의 변환에
T
가 완전한 타입이어야 함을 요구했음
|
요구되지 않음 |
| CWG 2006 | C++98 | cv 한정된 void 타입이 객체 타입이자 완전한 타입이었음 | 두 범주 모두에서 제외됨 |
| CWG 2448 | C++98 | cv 비한정 타입만 정수형 및 부동소수점 타입이 될 수 있었음 | cv 한정 타입을 허용함 |
| CWG 2630 | C++98 |
클래스 정의가 나타나는 번역 단위 외부에서
클래스가 완전한 타입으로 간주되는지 불분명했음 |
이 경우 클래스 정의가
도달 가능하다면 클래스는 완전한 타입임 |
| CWG 2643 | C++98 |
알려지지 않은 경계의 배열에 대한 포인터 타입을
완전하게 만들 수 없었음 (하지만 이미 완전한 타입임) |
포인터가 가리키는 배열 타입은
완전하게 만들 수 없음 |
| LWG 2139 | C++98 | "사용자 정의 타입"의 의미가 불분명했음 |
"프로그램 정의 타입"을
대신 정의하고 사용함 |
| LWG 3119 | C++11 | 클로저 타입이 프로그램 정의 타입인지 불분명했음 | 명확히 규정됨 |
참고문헌
- C++23 표준 (ISO/IEC 14882:2024):
-
- 6.8.2 기본 타입 [basic.fundamental]
- C++20 표준(ISO/IEC 14882:2020):
-
- 6.8.2 기본 타입 [basic.fundamental]
- C++17 표준 (ISO/IEC 14882:2017):
-
- 6.9.1 기본 타입 [basic.fundamental]
- C++14 표준(ISO/IEC 14882:2014):
-
- 3.9.1 기본 타입 [basic.fundamental]
- C++11 표준(ISO/IEC 14882:2011):
-
- 3.9.1 기본 타입 [basic.fundamental]
- C++98 표준(ISO/IEC 14882:1998):
-
- 3.9.1 기본 타입 [basic.fundamental]
참고 항목
| Type traits | 타입의 속성을 질의하기 위한 컴파일 타임 템플릿 기반 인터페이스 |
|
C documentation
for
Type
|
|
외부 링크
| 1. | Howard Hinnant의 C++0x 타입 트리 |