名稱空間
變體
操作

識別符號

來自 cppreference.com
< cpp‎ | 語言
 
 
C++ 語言
表示式
替代表示
字面量
布林字面量 - 整數字面量 - 浮點字面量
字元字面量 - 字串字面量 - nullptr (C++11)
使用者定義 (C++11)
工具
屬性 (C++11)
型別
typedef 宣告
類型別名宣告 (C++11)
型別轉換
記憶體分配
類特有的函式屬性
explicit (C++11)
static

特殊成員函式
模板
雜項
 
 

一個 識別符號 是由任意長度的數字、下劃線、小寫和大寫拉丁字母,以及大多數 Unicode 字元組成的序列。

一個有效識別符號的第一個字元必須是以下之一

  • 大寫拉丁字母 A-Z
  • 小寫拉丁字母 a-z
  • 下劃線
  • 任何具有 Unicode 屬性 XID_Start 的 Unicode 字元

一個有效識別符號的任何其他字元必須是以下之一

  • 數字 0-9
  • 大寫拉丁字母 A-Z
  • 小寫拉丁字母 a-z
  • 下劃線
  • 任何具有 Unicode 屬性 XID_Continue 的 Unicode 字元

具有屬性 XID_Start 和 XID_Continue 的字元列表可在 DerivedCoreProperties.txt 中找到。

識別符號區分大小寫(小寫字母和大寫字母不同),且每個字元都具有意義。每個識別符號必須符合 規範化形式 C

注意:大多數實現對 Unicode 識別符號的支援是有限的,例如 gcc(直到 10 版)

目錄

[編輯] 在宣告中

識別符號可以用於命名物件、引用、函式、列舉器、型別、類成員、名稱空間、模板、模板特化,引數包(C++11 起)、goto 標籤以及其他實體,但有以下例外:

  • 關鍵字識別符號不能用於其他目的。
  • 它們唯一可以作為非關鍵字使用的地方是 attribute-token 中(例如,[[private]] 是一個有效的屬性)。
(C++11 起)
  • 具有特殊含義的識別符號(finalimportmodule(C++20 起)override)在特定上下文中明確使用,而非作為常規識別符號。
    • 除非另有說明,如果給定的識別符號是否具有特殊含義存在歧義,則將其解釋為常規識別符號。
(C++11 起)
  • 以下形式的識別符號 (以 token 或預處理 token 形式出現,即不在 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 或宣告此類識別符號用於其內部需求,編譯器可以預定義此類非標準識別符號,並且名稱重整演算法可能假定其中一些識別符號未被使用。如果程式設計師使用此類識別符號,則程式格式錯誤,不需要診斷。

此外,在翻譯單元中 #define#undef 某些名稱是未定義行為,詳見 保留宏名稱

[編輯] 殭屍識別符號

從 C++14 起,一些識別符號已從 C++ 標準庫中刪除。它們列在 殭屍名稱列表 中。

然而,這些識別符號在特定上下文中仍為之前的標準化所保留。已刪除的成員函式名不能用作函式式宏的名稱,而其他已刪除的成員名不能用作可移植程式碼中物件式宏的名稱。

[編輯] 在表示式中

命名變數、函式、概念的特化(C++20 起)或列舉器的識別符號可以用作表示式。僅由識別符號組成的表示式的結果是識別符號命名的實體。表示式的值類別lvalue,如果識別符號命名的是函式、變數模板引數物件(C++20 起)或資料成員,否則為 rvalue(C++11 前)prvalue(C++11 起)(例如,列舉器rvalue(C++11 前)prvalue(C++11 起)表示式,概念的特化是布林 prvalue(C++20 起))。

[編輯] 型別

識別符號表示式的型別與其所命名實體的型別相同。

存在以下例外情況:

  • 如果(非限定)識別符號命名的實體是區域性實體,並且如果它在識別符號出現的宣告區域中未求值運算元之外被命名,將導致一箇中間的lambda 表示式透過複製捕獲它,那麼表示式的型別是類成員訪問表示式的型別,該表示式命名將在最內層此中間 lambda 表示式的閉包物件中宣告的非靜態資料成員。
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&
    };
}
  • 如果命名的實體是型別為 T 的模板引數的模板引數物件,則表示式的型別是 const T
(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 命名在名稱空間 signals2 中宣告的型別 connection,而 signals2 宣告在名稱空間 boost 中。

關鍵字 template 可能出現在限定識別符號中,以消除依賴模板名稱的歧義。

有關限定識別符號名稱查詢的詳細資訊,請參閱限定查詢

[編輯] 隱式成員訪問轉換

如果識別符號表示式 E 表示類 C 的某個非靜態非型別成員,並且滿足以下所有條件,則 E 被轉換為類成員訪問表示式 this->E

  • E 可能被求值
  • CE 處最內層的 enclosing class。
  • CE 處最內層 enclosing class 的基類。

此轉換不適用於模板定義上下文(請參見依賴名稱)。

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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
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 文件 關於 識別符號