命名空间
变体
操作

详述类型说明符

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句 (循环)
for
range-for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (在 C++17 前已弃用*)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
 
 

详述类型说明符可以用于引用之前声明的类名(class、struct 或 union)或之前声明的枚举名,即使该名称被非类型声明隐藏。它们也可以用于声明新的类名。

目录

[编辑] 语法

class-key class-name (1)
enum enum-name (2)
class-key attr (可选) identifier ; (3)
class-key - 其中之一 class, struct, union
class-name - 先前声明的类类型的名称,可选择性地限定,或者一个之前未声明为类型名称的标识符
enum-name - 先前声明的枚举类型的名称,可选择性地限定
attr - (自 C++11 起) 任意数量的属性
1) 用于类类型的详述类型说明符。
2) 用于枚举类型的详述类型说明符。
3) 仅由详述类型说明符组成的声明始终在包含该声明的作用域中声明由 identifier 命名的类类型。

不透明枚举声明 类似于形式 (3),但不透明枚举声明后的枚举类型是完整类型。

[编辑] 解释

形式 (3) 是详述类型说明符的特殊情况,通常称为类的前向声明,有关形式 (3) 的描述,请参阅 前向声明。以下内容仅适用于形式 (1)(2)

详述类型说明符中的 class-nameenum-name 可以是简单标识符,也可以是限定标识符。名称查找使用非限定名称查找限定名称查找,具体取决于它们的出现方式。但在任何情况下,都不会考虑非类型名称。

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)引入,并且 class-name 是非限定标识符,则详述类型说明符是 class-name 的类声明,目标作用域是最近的封闭命名空间或块作用域。

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;'
}

详述类型说明符中存在的 class-keyenum 关键字在种类上必须与详述类型说明符中名称所引用的声明一致。

  • enum 关键字必须用于引用枚举类型(无论是作用域枚举还是非作用域枚举)
  • union class-key 必须用于引用联合体
  • classstruct class-key 必须用于引用非联合体类类型(关键字 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]