详尽类型说明符
来自 cppreference.com
详尽类型说明符可用于引用以前声明的类名(class、struct 或 union)或以前声明的枚举名,即使该名称被 非类型声明隐藏。它们也可用于声明新的类名。
目录 |
[编辑] 语法
class-key class-name | (1) | ||||||||
enum enum-name |
(2) | ||||||||
class-key attr (可选) 标识符 ; |
(3) | ||||||||
class-key | - | 是 class、struct、union 之一 |
class-name | - | 先前声明的类类型的名称,可以 限定,或者是一个以前没有声明为类型名的标识符 |
enum-name | - | 先前声明的枚举类型的名称,可以 限定 |
attr | - | (自 C++11 起) 任意数量的 属性 |
1) 类类型的详尽类型说明符。
2) 枚举类型的详尽类型说明符。
不透明枚举声明 类似于形式 (3),但枚举类型在不透明枚举声明之后是完整类型。
[编辑] 解释
形式 (3) 是详尽类型说明符的一种特殊情况,通常称为类的前向声明,有关形式 (3) 的描述,请参见 前向声明。以下内容仅适用于形式 (1) 和 (2)。
详尽类型说明符中的 class-name 或 enum-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 }
如果名称查找没有找到之前声明的类型名称,则详细类型说明符由class
、struct
或union
(即,不是由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
类关键字必须用于引用联合。class
或struct
类关键字必须用于引用非联合类类型(关键字class
和struct
在这里是可互换的)。
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
是由详细类型说明符引入的。
[edit] 关键字
[edit] 参考资料
- 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]
本节不完整 原因:可能将 9.1[class.name]/2-3 中的大部分内容从 cpp/language/class 中提取出来 |