typedef 指定子
typedef- 型名を使用する場所ならどこでも使用できる別名を作成します。
説明
typedef 指定子は、宣言の decl-specifier-seq で使用されたとき、その宣言が typedef 宣言であり、関数やオブジェクトではなく typedef 名を宣言することを指定します。 同じ行でひとつまたは複数の識別子を宣言しても良く (例えば int と int へのポインタなど)、配列や関数型、ポインタや参照、クラス型などを宣言しても構いません。 この宣言で導入されたそれぞれの識別子は typedef 名となり、もしキーワード typedef が無かったならば宣言されたであろうオブジェクトや関数の型の同義語となります。
typedef 指定子は型指定子を除く他のいかなる指定子とも組み合わせることはできません。
typedef 名は既存の型の別名であり、新しい型の宣言ではありません。 typedef は既存の型名 (typedef 名を含む) の意味を変えるために使用することはできません。 いったん宣言された typedef 名は、もう一度同じ型を参照するためにのみ再宣言しても構いません。 typedef 名はそれらが可視なスコープでのみ有効です。 異なる関数やクラスでは同一の名前の型を異なる意味で定義しても構いません。
|
typedef struct X {}; // ill-formed
|
(C++17以上) |
リンケージ目的の typedef 名
形式的には、 typedef 宣言が無名クラスまたは列挙を定義する場合、そのクラス型または列挙型となるその宣言によって宣言された最初の typedef 名は、リンケージ目的でそのクラス型または列挙型を示すために使用されます。 例えば、 typedef struct { /* ... */ } S; の場合、 S はリンケージ目的の typedef 名です。 この方法で定義されたクラス型や列挙型は、 (無名名前空間内でなければ) 外部リンケージを持ちます。
|
この方法で定義された無名クラスは C 互換の要素のみを含むべきです。 特に、
また、すべてのメンバクラスもこれらの要件を (再帰的に) 満たさなければなりません。 |
(C++20以上) |
キーワード
ノート
型エイリアスは、 typedef と同じ機能を異なる構文で提供し、さらにテンプレート名にも適用できます。
例
// 単純な typedef。
typedef unsigned long ulong;
// 以下の2つのオブジェクトは同じ型です。
unsigned long l1;
ulong l2;
// もっと複雑な typedef。
typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10];
// 以下の2つのオブジェクトは同じ型です。
int a1[10];
arr_t a2;
// 「struct S」と書くのを回避するための一般的な C 言語のイディオム。
typedef struct {int a; int b;} S, *pS;
// 以下の2つのオブジェクトは同じ型です。
pS ps1;
S* ps2;
// エラー、記憶域クラス指定子は typedef 宣言では使用できません。
// typedef static unsigned int uint;
// typedef は decl-specifier-seq の中ならどこでも使用できます。
long unsigned typedef int long ullong;
// 普通に書くと「typedef unsigned long long int ullong;」です。
// 他の多くのメタ関数と同様に、 std::add_const はメンバ typedef を使用します。
template< class T>
struct add_const {
typedef const T type;
};
typedef struct Node {
struct listNode* next; // listNode という名前の新しい (不完全な) 構造体型を宣言します。
} listNode; // エラー、前に宣言された構造体の名前と衝突します。
関連項目
typedef 宣言 の C言語リファレンス
|