看着另一个问题,我意识到我不能通过头文件使用匿名命名空间中的对象或函数,因为它会导致类定义或内联函数中的 ODR 违规。如果是这种情况,那么是否可以安全地在inline
函数或类中使用命名const
或constexpr
static
对象?例如,如果CONSTANT
在下面的namespace
内,那将是不安全的,但是可以使用带有静态链接的常量吗?
// some header file to be included by multiple .cpp files
static const/*expr*/ int CONSTANT = 2;
inline int f() {
return CONSTANT;
}
class Cls {
int mem = CONSTANT;
};
这段代码没问题。完整的段落(C++14 [basic.def.odr/6.2])是:
在
D
的每个定义中,根据 3.4 查找的相应名称应指D
定义中定义的实体,或应指同一实体,在重载解析和部分模板专用化匹配后,除了名称可以指非易失性 具有内部链接或无链接的 const 对象,如果该对象在D
的所有定义中具有相同的文字类型,并且该对象使用常量表达式初始化,并且该对象未被 ODR 使用,并且该对象在D
的所有定义中具有相同的值;和
此用法确实符合"除了...和。。。而且...".part:
CONSTANT
这个名字实际上指的是具有内部链接的非易失性const
对象- 它在
f()
的所有定义中具有相同的文字类型。 - 它使用常量表达式
2
初始化。 - 它不是odr 使用的。
- 它在
f()
的所有定义中具有相同的值。
"它不是odr-used"这一点应该意味着"它不是在f()
中使用odr的"——也就是说,如果你碰巧在程序的其他地方使用odr-useCONSTANT
,它不会破坏f()
。