typedef 指定子
-
typedef- (おそらく複雑な) 型名の代わりにどこでも使用できるエイリアスを作成します。
-
目次 |
[編集] 説明
宣言で使用される場合、typedef 指定子は、その宣言が変数または関数宣言ではなく、typedef 宣言であることを指定します。
通常、typedef 指定子は宣言の先頭に現れますが、型指定子の後、または2つの型指定子の間に現れることも許可されています。typedef 指定子は、型指定子以外の他の指定子と組み合わせることはできません。
typedef 宣言は、同じ行に1つまたは複数の識別子 (例: int と int へのポインタ) を宣言したり、配列型や関数型、ポインタや参照、クラス型などを宣言したりできます。この宣言で導入されるすべての識別子はtypedef 名となり、これはキーワード typedef が削除された場合にそれがなるであろうオブジェクトまたは関数の型のシノニムです。
typedef 名は既存の型のエイリアスであり、新しい型の宣言ではありません。typedef を使用して、既存の型名 (typedef 名を含む) の意味を変更することはできません。一度宣言された typedef 名は、同じ型を再度参照するようにのみ再宣言できます。typedef 名は、それらが可視であるスコープ内でのみ有効です。異なる関数やクラス宣言では、異なる意味を持つ同じ名前の型を定義できます。
typedef 指定子は、関数パラメータの宣言や関数定義のdecl-specifier-seqには現れてはなりません。
void f1(typedef int param); // ill-formed typedef int f2() {} // ill-formed
typedef 指定子は、宣言子を含まない宣言には現れてはなりません。
typedef struct X {}; // ill-formed
[編集] リンケージ目的の typedef 名
typedef 宣言が名前のないクラスまたは列挙型を定義する場合、宣言によって宣言されたクラス型または列挙型の最初の typedef 名は、その型のリンケージ目的の typedef 名です。
例えば、typedef struct { /* ... */ } S; では、S はリンケージ目的の typedef 名です。このように定義されたクラスまたは列挙型は、外部リンケージを持ちます (名前のない名前空間内にある場合を除く)。
|
このように定義された名前のないクラスは、C互換の構文のみを含めるべきです。特に、以下を行ってはいけません。
また、すべてのメンバクラスもこれらの要件を満たす必要があります (再帰的に)。 |
(C++20以降) |
[編集] 注記
|
型エイリアスは、異なる構文を使用して typedef 宣言と同じ機能を提供し、テンプレート名にも適用できます。 |
(C++11以降) |
[編集] キーワード
[編集] 例
// simple typedef typedef unsigned long ulong; // the following two objects have the same type unsigned long l1; ulong l2; // more complicated typedef typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10]; // the following two objects have the same type int a1[10]; arr_t a2; // beware: the following two objects do not have the same type const intp_t p1 = 0; // int *const p1 = 0 const int *p2; // common C idiom to avoid having to write "struct S" typedef struct { int a; int b; } S, *pS; // the following two objects have the same type pS ps1; S* ps2; // error: storage-class-specifier cannot appear in a typedef declaration // typedef static unsigned int uint; // typedef can be used anywhere in the decl-specifier-seq long unsigned typedef int long ullong; // more conventionally spelled "typedef unsigned long long int ullong;" // std::add_const, like many other metafunctions, use member typedefs template<class T> struct add_const { typedef const T type; }; typedef struct Node { struct listNode* next; // declares a new (incomplete) struct type named listNode } listNode; // error: conflicts with the previously declared struct name // C++20 error: "struct with typedef name for linkage" has member functions typedef struct { void f() {} } C_Incompatible;
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 576 | C++98 | typedef は関数定義全体で許可されていなかった | 関数本体で許可された |
| CWG 2071 | C++98 | typedef は宣言子を含まない宣言に現れることができた | 現在禁止されている |
[編集] 関連項目
| C ドキュメント ( Typedef 宣言)
|