Namespaces
Variants

typedef specifier

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
  • typedef - (複雑な可能性のある)型名の代わりに使用できるエイリアスを作成します。

目次

説明

typedef 指定子は、 宣言 内で使用された場合、その宣言が変数や関数の宣言ではなく typedef宣言 であることを指定します。

通常、 typedef 指定子は宣言の先頭に現れますが、 型指定子 の後、または2つの型指定子の間に現れることも許可されています。 typedef 指定子は、型指定子を除く他の指定子と組み合わせることはできません。

typedef宣言は同じ行で1つまたは複数の識別子を宣言できます(例: int および int へのポインタ)。配列型や関数型、ポインタや参照、クラス型などを宣言することもできます。この宣言で導入される各識別子は typedef名 となり、キーワード typedef が削除された場合にその識別子が対象となるオブジェクトまたは関数の型のシノニムとなります。

typedef名は既存の型の別名であり、新しい型の宣言ではありません。 typedef は既存の型名(typedef名を含む)の意味を変更するために使用することはできません。一度宣言されると、typedef名は同じ型を参照するためにのみ再宣言できます。typedef名はそれが可視であるスコープ内でのみ有効です:異なる関数やクラス宣言では、同じ名前で異なる意味を持つ型を定義することができます。

typedef 指定子は、関数パラメータの宣言や function definition decl-specifier-seq 内に現れることはできません:

void f1(typedef int param); // 不適格な形式
typedef int f2() {}         // 不適格な形式

typedef 指定子は、宣言子を含まない宣言内に現れることはできません:

typedef struct X {}; // 不適格な形式

リンケージ目的のためのtypedef名

typedef宣言が無名の class または enumeration を定義する場合、その宣言によって宣言されたクラス型または列挙型の最初のtypedef名は、その型の linkage purposesのためのtypedef名 となります。

例えば、 typedef struct { /* ... */ } S ; において、 S はリンケージのためのtypedef名です。この方法で定義されたクラスまたは列挙型は、 外部リンケージ を持ちます(無名名前空間内でない限り)。

この方法で定義された無名クラスは、C互換の構成要素のみを含むべきです。特に、以下のことを行ってはなりません

また、すべてのメンバクラスも(再帰的に)これらの要件を満たさなければなりません。

(C++20以降)

注記

Type aliases はtypedef宣言と同じ機能を異なる構文で提供し、テンプレート名にも適用可能です。

(C++11以降)

キーワード

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;
// 注意: 以下の2つのオブジェクトは同じ型を持たない
const intp_t p1 = 0; // int *const p1 = 0
const int *p2;
// "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; // エラー: 以前に宣言された構造体名と競合
// C++20 エラー: "リンケージのためのtypedef名を持つ構造体"がメンバー関数を持つ
typedef struct { void f() {} } C_Incompatible;

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
CWG 576 C++98 typedef 関数定義全体で許可されていなかった 関数本体で許可
CWG 2071 C++98 typedef 宣言子を含まない宣言内に現れることができた 現在は許可されない

関連項目

C documentation for Typedef declaration
日本語訳:
C documentation for Typedef declaration
HTMLタグ、属性、C++固有の用語("Typedef declaration")は翻訳せず、元のフォーマットを保持しています。