Namespaces
Variants

Elaborated type specifier

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

目录

语法

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

不透明枚举声明 与形式 (3) 相似,但在不透明枚举声明之后,枚举类型将成为完整类型。

说明

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

详细类型说明符中的 class-name enum-name 可以是简单标识符,也可以是 qualified-id 。根据其表现形式,将通过 非限定名称查找 限定名称查找 来查找该名称。但无论哪种情况,都不会考虑非类型名称。

class T
{
public:
    class U;
private:
    int U;
};
int main()
{
    int T;
    T t; // 错误:找到局部变量T
    class T t; // 正确:找到 ::T,局部变量T被忽略
    T::U* u; // 错误:查找T::U时找到私有数据成员
    class T::U* u; // 正确:数据成员被忽略
}

如果名称查找未能找到先前声明的类型名称,且由 class struct union (即非 enum )引导的详细类型说明符中的 class-name 为非限定标识符,则该详细类型说明符将成为该class-name的类声明,其目标作用域为最近的外层命名空间或块作用域。

template<typename T>
struct Node
{
    struct Node* Next; // 正确:Node 的查找会找到注入类名
    struct Data* Data; // 正确:在全局作用域声明 Data 类型
                       // 同时声明数据成员 Data
    friend class ::List; // 错误:不能引入限定名称
    enum Kind* kind; // 错误:不能引入枚举类型
};
Data* p; // 正确:结构体 Data 已被声明

如果该名称指代的是 typedef 名称 类型别名 模板类型参数 别名模板特化 ,则程序非良构;否则,该详细类型说明符将名称引入声明的方式与 简单类型说明符 引入其类型名称的方式相同。

template<typename T>
class Node
{
    friend class T; // 错误:类型参数不能出现在详细类型说明符中;
                    // 注意:类似的声明 `friend T;` 是合法的。
};
class A {};
enum b { f, t };
int main()
{
    class A a; // 正确:等价于 'A a;'
    enum b flag; // 正确:等价于 'b flag;'
}

出现在详细类型说明符中的 类关键字 enum 关键字必须与详细类型说明符中名称所指代的声明种类保持一致。

  • 必须使用 enum 关键字来指代 枚举类型 (无论作用域或非作用域)
  • 必须使用 union 类关键字 来指代 联合体
  • 必须使用 class struct 类关键字 来指代非联合体类类型(此处关键字 class struct 可互换使用)。
enum class E { a, b };
enum E x = E::a; // 正确
enum class E y = E::b; // 错误:'enum class' 不能用作详细类型说明符
struct A {};
class A a; // 正确

当用作 模板实参 时, 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]