constexpr 在变量声明中的位置

constexpr position in variable declaration

通常我喜欢把"const"放在类型后面,如

int const foo1 = 123;

现在,如果我想声明第二个变量(甚至应该是 constexpr),我想使用相同的样式:

int constexpr foo2 = 123;

然而,这导致了对 运行 代码分析工具的警告(但是,我尝试过的所有编译器都接受它)。 C++ 标准是否强制要求 constexpr 只能在实际类型之前使用?

constexpr 是一个 decl-specifierintconst.

也是

其他decl-specifiers例如thread_localmutableexternvirtualexternfriendtypedefconstevalconstinitinline,以及其他 类型说明符 ,例如作为 volatilelongdoubleautosigneddecltype(...)、类型名称、由 class 引入的类型, enumunionstruct

decl-specifiers 序列构成声明的 decl-specifier-seq。在 decl-specifier-seq 之后通常是声明符列表,以逗号分隔,它们声明具有给定 decl-specifiers 的实体。 (但是例如 int* s; 中的 * 是声明符的一部分,而不是说明符序列。)

我认为标准中没有任何实例表明 decl-specifier-seq 的顺序有任何相关性。例如,以下编译没有问题,并且应该具有与说明符的常规顺序相同的含义:

struct { double volatile mutable long x = 1; } typedef const S;
inline S thread_local constexpr *s = {};

请参阅 C++ 标准的 post-C++20 草案,第 [dcl.spec] 节。它指定了 decl-specifier-seq 和各个说明符的语法。在本节的其余部分中,某些说明符组合是被禁止的,但未提及它们的顺序。


所以

int constexpr x;

constexpr int x;

是等价的。

但是不可能的是例如

int* constexpr x;

constexpr 在这里是声明符的一部分。可以写成

int constexpr* x;

虽然。

我想这使得将 constexpr 作为规则放在类型说明符之后令人困惑。它与 const 的规则相同,但 constexpr 应该只适用于整个声明,而不适用于类型或子类型。


我认为代码分析工具很可能只是在抱怨样式而不是语法的功能。将 constexpr 放在类型说明符后面是不常见的,因为将例如constlong long 中的两个 long 之间,如果说明符的顺序不常见,则可能难以阅读代码。