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

Objects references functions function template specializations を含む)、および expressions type と呼ばれる特性を持ち、これらエンティティに対して許可される操作を制限するとともに、本来は汎用的なビット列に意味論的な意味を与えます。

目次

型分類

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以降)
  • 標準浮動小数点型: float , double , long double およびそれらの cv修飾版 ;
(C++23以降)
  • オブジェクト型への左辺値参照;
  • 関数型への左辺値参照;
  • rvalue reference to object types;
  • rvalue reference to function types;
(C++11以降)
(C++11以降)
翻訳内容: - "scoped enumeration types" → "スコープ付き列挙型" - "see also" → "関連項目" - "(since C++11)" → "(C++11以降)" HTMLタグ、属性、` `/`
`/``タグ内のテキスト(`std::is_scoped_enum`)は翻訳せず、元のフォーマットを保持しています。C++専門用語も翻訳していません。
  1. signed char および unsigned char はナロウ文字型であるが、文字型ではない。言い換えれば、ナロウ文字型の集合は文字型の集合の部分集合ではない。

参照型および関数型以外のすべての非cv修飾型に対して、型システムはその型の3つの追加の cv修飾版 ( const volatile 、および const volatile ) をサポートします。

その他のカテゴリ

object type std::is_object も参照)は、関数型でも参照型でもなく、また(CV修飾された可能性のある) void でもない(CV修飾された可能性のある)型です。

以下の型はまとめて スカラ型 と呼ばれます( std::is_scalar も参照してください):

(C++11以降)
  • これらの型のCV修飾版

以下の型は総称して implicit-lifetime types と呼ばれます:

以下の型は総称して トリビアリーコピー可能型 と呼ばれる:

以下の型は総称して スタンダードレイアウト型 と呼ばれる:

(C++11以降)

型特性階層図

cpp types v3.svg

注記: SVG画像の要素はクリック可能ですが、まず新しいブラウザタブで図を開く必要があります

非推奨カテゴリ

以下の型は総称して POD型 と呼ばれる (参照: std::is_pod ):

  • スカラ型
  • PODクラス
  • これらの型の配列
  • これらの型のcv修飾版
(C++20で非推奨)

以下の型は総称して トリビアル型 と呼ばれる (参照: std::is_trivial ):

(C++11以降)
(C++26で非推奨)

プログラム定義型

プログラム定義特殊化( program-defined specialization )は、C++ standard library の一部ではなく、実装によって定義されていない explicit specialization または partial specialization です。

プログラム定義型は以下のいずれかの型です:

(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のvectorの宣言
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); // エラー:ストレージクラス指定子は型指定子シーケンスの一部ではない
std::function<inline void(int)> f; // エラー:関数指定子も同様に不可

宣言文法のうち名前が除去された declarator 部分は、 abstract-declarator と呼ばれます。

Type-idは以下の状況で使用されることがあります:

(C++17まで)

Type-idは以下の状況で一部変更を加えて使用することができます:

  • 関数の パラメータリスト 内(パラメータ名が省略されている場合)、型IDは type-specifier-seq の代わりに decl-specifier-seq を使用する(特に、いくつかのストレージクラス指定子が許可される);
  • ユーザー定義変換関数 の名前では、抽象宣言子に関数または配列演算子を含めることができない。

詳細型指定子

詳細型指定子は、以前に宣言されたクラス名(class、struct、union)または列挙型名を参照するために使用できます。たとえその名前が 非型宣言によって隠蔽されていた場合でも 使用可能です。また、新しいクラス名を宣言するためにも使用できます。

詳細については elaborated type specifier を参照してください。

静的型

プログラムのコンパイル時解析によって得られる式の型は、 static type (静的型)として知られています。静的型はプログラムの実行中に変化しません。

動的型

何らかの glvalue expression polymorphic object を参照する場合、その最も派生したオブジェクトの型はdynamic typeとして知られています。

// 与えられたもの
struct B { virtual ~B() {} }; // ポリモーフィック型
struct D : B {};               // ポリモーフィック型
D d; // 最も派生したオブジェクト
B* ptr = &d;
// (*ptr)の静的型はB
// (*ptr)の動的型はD

prvalue式の場合、動的型は常に静的型と同じです。

不完全型

以下の型は 不完全型 です:

  • void (場合によっては cv 修飾される可能性あり);
  • 不完全定義オブジェクト型

その他のすべての型は完全型です。

以下のいずれかのコンテキストでは、型 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は完全型
}
  • 配列オブジェクトの宣言された型は、不完全なクラス型の配列であり、したがって不完全である可能性があります。クラス型が翻訳単位の後半で完全化された場合、配列型は完全型になります。これら2つの時点における配列型は同じ型です。
  • 配列オブジェクトの宣言された型は、未知のサイズの配列であり、したがって翻訳単位のある時点では不完全であり、後で完全になる可能性があります。これら2つの時点における配列型(「 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型階層