Namespaces
Variants

Type

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

객체 , 참조 , 함수 (여기에는 함수 템플릿 특수화 를 포함함), 그리고 표현식 타입 이라는 속성을 가지며, 이는 해당 개체들에 허용되는 연산을 제한함과 동시에 일반적인 비트 시퀀스에 의미론적 의미를 부여합니다.

목차

타입 분류

C++ 타입 시스템은 다음의 타입들로 구성됩니다:

(C++11부터)
  • 타입 bool ;
  • 문자 타입:
  • 좁은 문자 타입:
  • 일반 문자 타입: char , signed char , unsigned char [1]
  • 타입 char8_t
(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부터)
  • 확장 부동소수점 타입 (다음을 포함):
(C++23부터)
  • 객체 타입에 대한 lvalue 참조;
  • 함수 타입에 대한 lvalue 참조;
  • rvalue reference to object types;
  • rvalue reference to function types;
(C++11부터)
(C++11부터)
  1. 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) 라고 합니다:

다음 유형들을 총칭하여 trivially copyable types (사소하게 복사 가능한 타입)이라고 합니다:

다음 유형들을 총칭하여 standard-layout types (표준 레이아웃 타입)이라고 합니다:

(C++11부터)

타입 트레이트 계층 구조 다이어그램

cpp types v3.svg

참고: SVG 이미지의 요소들은 클릭 가능하지만, 먼저 새 브라우저 탭에서 다이어그램을 열어야 합니다

사용 중단된 카테고리

다음 유형들을 통칭하여 POD 타입 이라고 합니다 (참조: std::is_pod ):

  • 스칼라 타입
  • POD 클래스
  • 위 유형들의 배열
  • 위 유형들의 cv 한정 버전
(C++20에서 사용 중단됨)

다음 유형들을 통칭하여 trivial 타입 이라고 합니다 (참조: std::is_trivial ):

(C++11부터)
(C++26에서 사용 중단됨)

프로그램 정의 타입

프로그램 정의 특수화 는 C++ 표준 라이브러리 의 일부가 아니며 구현에 의해 정의되지 않은 명시적 특수화 또는 부분 특수화 입니다.

프로그램 정의 타입 은 다음 유형 중 하나입니다:

(since C++11)

타입 명명

name 은 다음 방법을 통해 타입을 참조하도록 선언될 수 있습니다:

이름이 없는 타입들은 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 라고 부릅니다.

타입 식별자는 다음과 같은 상황에서 사용될 수 있습니다:

(C++17까지)

타입 식별자는 다음과 같은 상황에서 일부 수정과 함께 사용될 수 있습니다:

  • 함수의 매개변수 목록 에서 (매개변수 이름이 생략된 경우), type-id는 type-specifier-seq 대신 decl-specifier-seq 을 사용합니다 (특히, 일부 storage class specifiers가 허용됨);
  • 사용자 정의 변환 함수 의 이름에서, abstract declarator는 함수 또는 배열 연산자를 포함할 수 없습니다.

정규화된 타입 지정자

정교화된 타입 지정자는 이전에 선언된 클래스 이름(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);
  • 불완전하게 정의된 객체 타입들 :

다른 모든 타입은 완전합니다.

다음 중 어느 하나의 상황에서도 타입 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 의 알려지지 않은 경계 배열"과 " N T 배열")은 서로 다른 타입입니다.

알 수 없는 경계를 가진 배열에 대한 포인터나 참조의 유형은 영구적으로 불완전한 유형을 가리키거나 참조합니다. 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 타입의 속성을 질의하기 위한 컴파일 타임 템플릿 기반 인터페이스

외부 링크

1. Howard Hinnant의 C++0x 타입 트리