文中涉及语法的通过BNF表示
文中例程是本人自己理解和看网页的例子整理出来的,如有错误麻烦及时指正,水平有限,望与各位多多交流
这一节是对整个声明的总括,之后会有所有的声明的Blog的
了解声明,首先要知道以下三个关键字的意思:
attr //属性序列C++11
decl-specifier-seq //指定符序列
init-declarator-list //声明器带可选的初始化逗号分隔列表
一个声明可以由各种声明来构成,这章Blog只是记录其中的简单声明,以及没有decl-specifier-seq的声明
一:没有decl-specifier-seq的声明
这类声明由:
[attr]<declarator>
组成,这类声明最直接的例子就是类内的各种无返回值的函数声明,类似构造,析构,类型转换函数等。
二:简单声明(能出现在块的声明之一)
一个简单声明由上面三个关键字选择性组成,分别有:
<decl-specifier-seq>[init-declarator-list]
<attr><decl-specifier-seq><init-declarator-list>
现在着重来说下
decl-specifier-seq 和 init-declarator-list
decl-specifier-seq 指定符
指定符包括typedef
函数指定符(inline,virtual,explicit)
变量的inline指定符
friend指定符
constexpr指定符
存储类型指定符
类型指定符
并且有规则:
一个 decl-specifier-seq 中只允许一个类型指定符,除了下列例外:
- const 能与自身外的任何类型指定符组合。
- volatile 能与自身外的任何类型指定符组合。
- signed 或 unsigned 能与 char 、 long 、 short 或 int 组合。
- short 或 long 能与 int 组合。
- long 能与 double 组合。
- long 能与 long 组合。
除以上规则,其他的组合均为错误。
可以说,decl-specifier-seq是由类型修饰符,类型限定符和类型名构成的
init-declarator-list 声明器序列
其中声明器序列又需要注意以下关键字:
declarator //声明器
initializer //可选的初始化器
requires-clause(C++20暂时不做记录)
通常init-declarator-list是一个或多个init-declarator的逗号分隔列表
其组合请查看原网页(很多,但是有例子就会很好想)
(例子这里的可选的属性都不加了,因为VS2017最新的草案里面很多属性还是不给用)
这里实际上可以理解为是对当前这个标识符所代表的数据的描述,比如:int const *a,首先表明了a是一个const类型的指针。
class M12
{
public:
int j = 2;
void CFC()[[]];
int *fccc()const noexcept[[]]; //(9)
};
void M12::CFC()[[]]{ j = 3; } //(2)定义
namespace M11
{
void FC() {}
}
void NFC() {}
template<typename... _Ty> //(3)
void TFC(_Ty... args[[deprecated]]){}
M12 *[[]] const fcc(); //(8)
int main()
{
void M11::FC() [[]]; //(2)重新声明
void NFC() [[]]; //(1)
M12 js;
js.CFC();
const M12 *[[]] const jss = &js; //(4) VS2017下划红但是可以执行编译
int M12::*[[]] const pem = &M12::j;
void (M12::*pfc)() = &M12::CFC; //(5)
//void M12::*[[]] const pfcp)() = &M12::CFC; (5)error是我的打开方式不对?求各位知道的长辈指点迷津一下
const int &[[]]j = 45; //(6)其中const int是decl-specifier-seq
int &&[[]]jj = 46; //(7)
return 0;
}