名稱空間
變體
操作

細化型別說明符

來自 cppreference.com
< cpp‎ | 語言
 
 
C++ 語言
 
 

即使名稱被非型別宣告隱藏,詳細型別說明符也可用於引用先前宣告的類名(class、struct 或 union)或先前宣告的列舉名。它們還可用於宣告新的類名。

目錄

[編輯] 語法

類鍵 類名 (1)
enum 列舉名 (2)
類鍵 屬性 (可選) 識別符號 ; (3)
類鍵 - classstructunion 之一
類名 - 先前宣告的類型別的名稱,可選地限定,或未曾宣告為型別名稱的識別符號
列舉名 - 先前宣告的列舉型別的名稱,可選地限定
屬性 - (自 C++11 起) 任意數量的屬性
1) 類型別的詳細型別說明符。
2) 列舉型別的詳細型別說明符。
3) 僅由詳細型別說明符組成的宣告總是宣告一個類型別,其名稱由包含該宣告的作用域中的識別符號命名。

不透明列舉宣告類似於形式(3),但在不透明列舉宣告之後,列舉型別是一個完整型別。

[編輯] 說明

形式(3)是詳細型別說明符的一個特殊情況,通常被稱為類的前向宣告;有關形式(3)的描述,請參見前向宣告。以下僅適用於形式(1)(2)

詳細型別說明符中的類名列舉名可以是一個簡單的識別符號,也可以是一個限定符-id。名稱根據其出現情況使用非限定名稱查詢限定名稱查詢進行查詢。但在任何一種情況下,都不考慮非型別名稱。

class T
{
public:
    class U;
private:
    int U;
};
 
int main()
{
    int T;
    T t; // error: the local variable T is found
    class T t; // OK: finds ::T, the local variable T is ignored
    T::U* u; // error: lookup of T::U finds the private data member
    class T::U* u; // OK: the data member is ignored
}

如果名稱查詢未找到先前宣告的型別名稱,並且詳細型別說明符由classstructunion(即不是由enum)引入,並且類名是一個非限定識別符號,則詳細型別說明符是類名的類宣告,並且目標作用域是最近的封閉名稱空間或塊作用域。

template<typename T>
struct Node
{
    struct Node* Next; // OK: lookup of Node finds the injected-class-name
    struct Data* Data; // OK: declares type Data at global scope
                       // and also declares the data member Data
    friend class ::List; // error: cannot introduce a qualified name
    enum Kind* kind; // error: cannot introduce an enum
};
 
Data* p; // OK: struct Data has been declared

如果該名稱指的是typedef 名稱類型別名模板型別引數別名模板特化,則程式是病態的,否則詳細型別說明符以與簡單型別說明符引入其型別名稱相同的方式將該名稱引入到宣告中。

template<typename T>
class Node
{
    friend class T; // error: type parameter cannot appear in an elaborated type specifier;
                    // note that similar declaration `friend T;` is OK.
};
 
class A {};
enum b { f, t };
 
int main()
{
    class A a; // OK: equivalent to 'A a;'
    enum b flag; // OK: equivalent to 'b flag;'
}

詳細型別說明符中存在的類鍵enum關鍵字必須與其所引用的宣告的種類一致。

  • enum關鍵字必須用於引用列舉型別(無論帶作用域還是不帶作用域)
  • union 類鍵必須用於引用聯合
  • classstruct 類鍵必須用於引用非聯合類型別(關鍵字classstruct在此處可互換)。
enum class E { a, b };
enum E x = E::a; // OK
enum class E y = E::b; // error: 'enum class' cannot introduce an elaborated type specifier
 
struct A {};
class A a; // OK

當用作模板引數時,class T是一個名為T的型別模板引數,而不是一個型別T由詳細型別說明符引入的無名非型別引數。

[編輯] 關鍵字

class, struct, union, enum

[編輯] 參考

  • C++23 標準 (ISO/IEC 14882:2024)
  • 6.5.6 詳細型別說明符 [basic.lookup.elab]
  • 9.2.9.4 詳細型別說明符 [dcl.type.elab]
  • C++20 標準 (ISO/IEC 14882:2020)
  • 6.5.4 詳細型別說明符 [basic.lookup.elab]
  • 9.2.8.3 詳細型別說明符 [dcl.type.elab]
  • C++17 標準 (ISO/IEC 14882:2017)
  • 6.4.4 詳細型別說明符 [basic.lookup.elab]
  • 10.1.7.3 詳細型別說明符 [dcl.type.elab]
  • C++14 標準 (ISO/IEC 14882:2014)
  • 3.4.4 詳細型別說明符 [basic.lookup.elab]
  • 7.1.6.3 詳細型別說明符 [dcl.type.elab]
  • C++11 標準 (ISO/IEC 14882:2011)
  • 3.4.4 詳細型別說明符 [basic.lookup.elab]
  • 7.1.6.3 詳細型別說明符 [dcl.type.elab]
  • C++98 標準 (ISO/IEC 14882:1998)
  • 3.4.4 詳細型別說明符 [basic.lookup.elab]
  • 7.1.5.3 詳細型別說明符 [dcl.type.elab]