名前空間
変種
操作

識別子

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

識別子 (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ラベル、およびその他のエンティティを命名するために使用できますが、以下の例外があります。

  • キーワードである識別子は、他の目的で使用することはできません。
  • キーワードでないものとして使用できる唯一の場所は、attribute-token(属性トークン)の中です(例:[[private]] は有効な属性です)。
(C++11以降)
  • 特定の演算子や句読点の代替表現である識別子は、他の目的で使用することはできません。
  • 特別な意味を持つ識別子(final, import, module(C++20から) および override)は、通常の識別子としてではなく、特定の文脈で明示的に使用されます。
    • 特に指定がない限り、ある識別子が特別な意味を持つかどうかについての曖昧さは、そのトークンを通常の識別子として解釈することで解決されます。
(C++11以降)
  • user-defined-string-literal(ユーザー定義文字列リテラル)(例:operator ""id)の中ではなく、(C++11から)トークンまたは前処理トークンとして現れる、以下のいずれかの形式の識別子は予約されています。
    • グローバル名前空間において、アンダースコアで始まる識別子
    • 二重アンダースコアを含むか、アンダースコアに続けて大文字が続く識別子。ただし、以下の識別子を除く。
(C++11以降)
  • 標準ライブラリで定義されている以下のマクロ
  • C互換マクロ __alignas_is_defined__alignof_is_defined<stdalign.h> で定義)
  • C互換マクロ __bool_true_false_are_defined<stdbool.h> で定義)
(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++20以降)
(C++11以降)

[編集] 非修飾識別子

適切に宣言された識別子に加えて、以下のものも式の中で同じ役割で使用できます。

(C++11以降)
  • テンプレート名とそれに続く引数リスト。例:MyTemplate<int>
  • 文字 ~ とそれに続くクラス名。例:~MyClass
  • 文字 ~ とそれに続く decltype 指定子。例:~decltype(str)
(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評価される可能性がある
  • CE の位置で最も内側にある囲むクラスである。
  • CE の位置で最も内側にある囲むクラスの基底クラスである。

この変換はテンプレート定義の文脈では適用されません(依存名を参照)。

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
  • ユーザー定義リテラル演算子名(operator ""_km
(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
English 日本語 中文(简体) 中文(繁體)