識別子
識別子 (identifier) は、数字、アンダースコア、ラテン文字の小文字と大文字、そしてほとんどのUnicode文字からなる、任意の長さのシーケンスです。
有効な識別子の最初の文字は、以下のいずれかでなければなりません。
- ラテン文字の大文字 A-Z
- ラテン文字の小文字 a-z
- アンダースコア
- Unicodeプロパティ XID_Start を持つ任意のUnicode文字
有効な識別子の2文字目以降は、以下のいずれかでなければなりません。
- 数字 0-9
- ラテン文字の大文字 A-Z
- ラテン文字の小文字 a-z
- アンダースコア
- Unicodeプロパティ XID_Continue を持つ任意のUnicode文字
プロパティXID_StartおよびXID_Continueを持つ文字のリストは、DerivedCoreProperties.txt に記載されています。
識別子は大文字と小文字を区別し(小文字と大文字は異なるものとして扱われます)、すべての文字が意味を持ちます。すべての識別子は正規化形式C (Normalization Form C) に適合しなければなりません。
注意: ほとんどの実装ではUnicode識別子のサポートは限定的です。例: gcc (10まで)。
目次 |
[編集] 宣言において
識別子は、オブジェクト、参照、関数、列挙子、型、クラスメンバー、名前空間、テンプレート、テンプレート特殊化、パラメータパック(C++11から)、gotoラベル、およびその他のエンティティを命名するために使用できますが、以下の例外があります。
- キーワードである識別子は、他の目的で使用することはできません。
|
(C++11以降) |
- 特定の演算子や句読点の代替表現である識別子は、他の目的で使用することはできません。
|
(C++11以降) |
- user-defined-string-literal(ユーザー定義文字列リテラル)(例:operator ""id)の中ではなく、(C++11から)トークンまたは前処理トークンとして現れる、以下のいずれかの形式の識別子は予約されています。
- グローバル名前空間において、アンダースコアで始まる識別子
- 二重アンダースコアを含むか、アンダースコアに続けて大文字が続く識別子。ただし、以下の識別子を除く。
- 定義済みマクロ(言語機能テストマクロを含む)(C++20から)
| (C++11以降) |
|
(C++11以降) |
| (C++20以降) |
ここでの「予約されている」とは、標準ライブラリのヘッダが内部的な目的でそのような識別子を #define または宣言すること、コンパイラがその種の非標準識別子を事前定義する可能性があること、そして名前マングリングのアルゴリズムがこれらの識別子の一部が使用されていないと仮定する可能性があることを意味します。プログラマがそのような識別子を使用した場合、プログラムは不適格 (ill-formed) となりますが、診断は要求されません。
加えて、翻訳単位内で特定の名前を #define または #undef することは未定義動作です。詳細は 予約済みマクロ名 を参照してください。
[編集] ゾンビ識別子
C++14以降、いくつかの識別子がC++標準ライブラリから削除されました。それらはゾンビ名のリストに記載されています。
しかし、これらの識別子は、以前の標準化のために特定の文脈では依然として予約されています。削除されたメンバ関数名は関数形式マクロの名前として使用してはならず、その他の削除されたメンバ名は移植性のあるコードではオブジェクト形式マクロの名前として使用してはなりません。
[編集] 式において
変数、関数、コンセプトの特殊化、(C++20から)または列挙子を名指す識別子は、式として使用できます。識別子のみからなる式の結果は、その識別子によって名指されたエンティティです。式の値カテゴリは、識別子が関数、変数、テンプレートパラメータオブジェクト(C++20から)、またはデータメンバを名指す場合は左辺値 (lvalue) であり、それ以外の場合(例:列挙子は右辺値 (rvalue)(C++11まで)純粋右辺値 (prvalue)(C++11から)式、コンセプトの特殊化はbool型の純粋右辺値(C++20から))は右辺値(C++11まで)純粋右辺値(C++11から)です。
[編集] 型
識別子式の型は、それが名指すエンティティの型と同じです。
|
以下の例外が存在します。
void f() { float x, &r = x; [=] { decltype(x) y1; // y1 has type float decltype((x)) y2 = y1; // y2 has type float const& because this lambda // is not mutable and x is an lvalue decltype(r) r1 = y1; // r1 has type float& decltype((r)) r2 = y2; // r2 has type float const& }; }
|
(C++11以降) |
[編集] 非修飾識別子
適切に宣言された識別子に加えて、以下のものも式の中で同じ役割で使用できます。
- 関数記法におけるオーバーロードされた演算子名。例:operator+ や operator new
- ユーザー定義変換関数名。例:operator bool
|
(C++11以降) |
- テンプレート名とそれに続く引数リスト。例:MyTemplate<int>
- 文字 ~ とそれに続くクラス名。例:~MyClass
|
(C++11以降) |
|
(C++26以降) |
これらは識別子とともに非修飾識別子式として知られています。
[編集] 修飾識別子
修飾識別子式は、非修飾識別子式の前にスコープ解決演算子 :: が付き、任意で、スコープ解決演算子で区切られた以下のいずれかのシーケンスが前に付くものです。
- 名前空間名
- クラス名
|
(C++11以降) |
|
(C++26以降) |
例えば、式 std::string::npos は、名前空間 std 内のクラス string 内の静的メンバ npos を名指す式です。式 ::tolower は、グローバル名前空間内の関数 tolower を名指します。式 ::std::cout は、トップレベルの名前空間である名前空間 std 内のグローバル変数 cout を名指します。式 boost::signals2::connection は、名前空間 boost 内で宣言された名前空間 signals2 内で宣言された型 connection を名指します。
キーワード template は、依存テンプレート名の曖昧さを解消するために必要に応じて修飾識別子内に現れることがあります。
修飾識別子の名前探索の詳細については、修飾名探索を参照してください。
[編集] 暗黙のメンバーアクセス変換
識別子式 E があるクラス C の非静的非型メンバを示し、かつ以下の条件がすべて満たされる場合、E はクラスメンバアクセス式 this->E に変換されます。
- E がメンバアクセス演算子の右オペランドではない。
- E が修飾識別子式である場合、E がアドレス演算子の括弧で囲まれていないオペランドではない。
- 以下のいずれかの条件が満たされる。
- E が評価される可能性がある。
-
Cが E の位置で最も内側にある囲むクラスである。 -
Cが E の位置で最も内側にある囲むクラスの基底クラスである。
この変換はテンプレート定義の文脈では適用されません(依存名を参照)。
struct X { int x; }; struct B { int b; }; struct D : B { X d; void func() { d; // OK, will be transformed into this->d b; // OK, will be transformed into this->b x; // Error: this->x is ill-formed d.x; // OK, will be transformed into this->d.x // instead of d.this->x or this->d.this->x } };
[編集] 名前
名前とは、エンティティを参照するために以下のいずれかを使用することです。
- 識別子
- 関数記法におけるオーバーロードされた演算子名(operator+、operator new)
- ユーザー定義変換関数名(operator bool)
|
(C++11以降) |
- テンプレート名とそれに続く引数リスト(MyTemplate<int>)
すべての名前は、宣言によってプログラムに導入されます。複数の翻訳単位で使用される名前は、リンケージに応じて、同じエンティティまたは異なるエンティティを参照することがあります。
コンパイラがプログラム中で未知の名前に遭遇した場合、テンプレート宣言および定義内の依存名を除き、名前探索によってその名前を導入した宣言と関連付けます(これらの名前については、コンパイラはそれらが型、テンプレート、または他のエンティティを名指すかを判断し、これには明示的な曖昧さの解消が必要な場合があります)。
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 1440 | C++11 | :: の前にある decltype 式は任意の型を示すことができた |
クラス型しか示せない または列挙型 |
| CWG 1963 | C++11 | 数字、非数字以外の実装定義文字 および汎用文字名が識別子で使用できた |
禁止された |
| CWG 2521 | C++11 | user-defined-string-literal 内の識別子 リテラル演算子は通常通り予約されていた |
ルールは異なる |
| CWG 2771 | C++98 | &a はクラス文脈で &this->a に変換されなかった | 変換される |
| CWG 2777 | C++20 | 識別子式の型が不明確だった それがテンプレートパラメータオブジェクトを名指す場合 |
明確化された |
| CWG 2818 | C++98 | 定義済みマクロ名は予約されていた | 予約されていない |
[編集] 関連項目
| C ドキュメント の Identifiers
|