【注】本文是Declarations的翻译和注解版。
https://msdn.microsoft.com/en-us/library/f432x8c6.aspx
1、声明:
我们通过声明往C++程序中引入(或重新引入)名字。Definitions are declarations that are sufficient to use the entity identified by the name(不知如何翻译,意思是定义也是一种声明)。不同种类的实体其声明也是不同的,具体如下所示:
- 函数声明(Function declaration)
- 模板声明(Template declaration)
- 显式模板实例化(Explicit template instantiation)
- 显式模板具体化(Explicit template specialization)
- 命名空间定义(Namespace definition)
- 链接具体化(Linkage specification)
- 属性声明(Attribute declaration)(C++11)
- 空声明(Empty declaration)
- 块声明(Block declaration)(【注】块声明指可以出现在块中的声明)。它们可以是以下的声明:
-
- asm definition
- type alias declaration
- namespace alias definition
- using declaration
- using directive
- static assert declaration
- opaque enum declaration
- 简单声明(simple declaration)
简单声明是一条引入、创建一个或多个标识符(一般是变量)的语句。其语法规则如下:
attr(optional) decl-specifier-seq(optional) init-declarator-list(optional) ;
(1)
- attr(C++11) 任意数目的属性序列。
- decl-specifier-seq 类型修饰符序列。它仅在声明构造函数,析构函数和用户定义类型转换函数(type conversion functions)时是可选的。
- init-declarator-list 逗号分隔的声明符(每个声明符可以有初始化值)列表。当声明有名类/结构体/联合体或有名枚举变量时Init-declarator-list是可选的。
1.1、修饰符(Specifiers)
decl-specifier-seq是由一个或多个修饰符以空白符间隔组成。修饰符有以下六大类:
- typedef修饰符:如果出现这个修饰符,整个声明就是一个类型定义声明,每个声明符都引入了一个新的类型名,而不是一个对象或函数。
- 函数修饰符(inline、virtual、explicit):这三个修饰符只能在函数声明中使用。
- friend修饰符:这个修饰符只能在函数或类类型声明中使用。
- constexpr修饰符:这个修饰符可以在变量定义,函数、函数模板声明,字面量类型静态数据成员的声明中使用。
- 存储类型修饰符(register、static、thread local(C++11)、extern、mutable):一个声明中只能使用一种存储类型修饰符,但是thread local可以与extern或static一起出现。
- 类型修饰符,又可以细分为以下几种情况:
-
- class修饰符(class specifier)
- enum修饰符(enum specifier)
- 简单类型修饰符(simple type specifier)
-
- 基本类型(fundamental type、base type)关键字:char, char16_t, char32_t (C++11), wchar_t, bool, short, int, long, signed, unsigned, float, double, void
- auto(C++11)
- decltype修饰符(C++11)
- 先前声明过的类类型名(限定或未限定)
- 先前声明过的枚举类型名(限定或未限定)
- 先前声明过的typedef名或type alias(C++11)(限定或未限定)
- any keyword that names a fundamental type: char, char16_t, char32_t (since C++11), wchar_t, bool, short, int, long, signed, unsigned, float, double, void
(since C++11) |
-
-
- previously declared class name (optionally qualified)
- previously declared enum name (optionally qualified)
- previously declared typedef-name or type alias (since C++11) (optionally qualified)
- template name with template arguments (optionally qualified, optionally using template disambiguator)
- elaborated type specifier
-
- the keyword class, struct, or union, followed by the identifier (optionally qualified), previously defined as the name of a class, struct, or union.
- the keyword class, struct, or union, followed by template name with template arguments (optionally qualified, optionally using template disambiguator), previously defined as the name of a class template.
- the keyword enum followed by the identifier (optionally qualified), previously declared as the name of an enumeration.
-
- only one type specifier is allowed in a decl-specifier-seq, with the following exceptions:
- -
const
can be combined with any type specifier except itself. - -
volatile
can be combined with any type specifier except itself. - -
signed
orunsigned
can be combined withchar
,long
,short
, orint
. - -
short
orlong
can be combined withint
. - -
long
can be combined withdouble
.
|
(since C++11) |
Attributes may appear in decl-specifier-seq, in which case they apply to the type determined by the preceding specifiers.
The only specifier that is allowed to appear twice in a decl-specifier-seq is |
(since C++17) |