C++中的constexpr关键字放置位置

9

最近我在代码中开始使用更多的C++11特性,我一直在思考constexpr关键字的位置是否会影响常量类型之前或之后。

样式1:

constexpr int FOO = 1;
constexpr auto BAR = "bar";

样式 2:

int constexpr FOO = 1;
auto constexpr BAR = "bar";

我更喜欢使用样式2来放置const关键字,如果以相同的方式放置constexpr关键字,代码会更加一致。不过,这种做法是否被认为是不好的惯例呢?还是因为我没见过有人像这样写而有其他问题呢?


同时还有一个不错的解释:东方const但西方constexpr - Dan Saks - starriet
2个回答

11

它是一个类似于longshortunsigned等的限定符。它们都可以移动位置。例如,下面这两个声明是等价且有效的:

int long const long unsigned constexpr foo = 5;
constexpr const unsigned long long int foo = 5;

按照惯例,constexpr 应该出现在类型名称之前。如果你把它放在后面可能会让其他人感到困惑,但从技术上讲是有效的。由于 constexpr 的作用与 const 不同,我认为把它放在右边没有同样的好处。例如,你不能这样写:int constexpr * constexpr foo。事实上,int constexpr * foo 将不允许你重新分配 foo,而是应用于 foo 指向的内容,所以如果你期望与 const 相同类型的语义,将其放在右边可能会产生误导。

总结一下:

int constexpr foo = 0; // valid
int constexpr * constexpr foo = nullptr; // invalid
int* constexpr foo = nullptr; // invalid
int constexpr * foo = nullptr; // valid
constexpr int* foo = nullptr; // valid and same as previous

仅就措辞而言,“它们都可以移动”可能被理解为“无论您将const放在哪里都没有关系”,但实际情况并非如此,因为它会改变含义。 - AlexD
@AlexD,没错,我可能有点过于简化了。主要观点是它们可以以任何顺序出现,在“基本类型”(例如int)之前或之后,直到像*这样的东西,语法开始变得更加具体。声明语法并不是最简单的部分之一。 - chris
当然。就像我说的那样,我的评论只是关于措辞的问题 :-). - AlexD
相关的非终端符号是“decl-specifier-seq”,但这也不是特别容易理解。 - T.C.
实际上,如果在“声明说明符序列”部分内(而不是在诸如 * 之后的声明符部分内),它们(声明说明符)确实可以移动。此外,这个答案这个视频 很有帮助。 - starriet

1

msdn 将语法定义为:

constexpr 字面类型 标识符 = 常量表达式; constexpr 字面类型 标识符 { 常量表达式 };constexpr 字面类型 标识符(params );constexpr ctor (params);

这意味着您应该将其用于左侧。

编辑:

新规范:关键字constexpr是一个声明说明符;请按照以下方式修改[ISO03,§7.1]中的语法:

1 可以在声明中使用的说明符为 decl-specifier:

存储类说明符

类型说明符

函数说明符

friend

typedef

constexpr

有关此说明符的解释,请单击此处

总之,@chris的答案是正确的 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接