C++ 在头文件中使用符合ODR的常量
通过查看,我意识到我不能通过头文件使用匿名名称空间中的对象或函数,因为这会导致类定义或内联函数中的ODR冲突。如果是这种情况,那么是否可以在C++ 在头文件中使用符合ODR的常量,c++,c++11,one-definition-rule,C++,C++11,One Definition Rule,通过查看,我意识到我不能通过头文件使用匿名名称空间中的对象或函数,因为这会导致类定义或内联函数中的ODR冲突。如果是这种情况,那么是否可以在内联函数或类中安全地使用命名的const或constepr静态对象?例如,如果常量位于下面的名称空间内,则不安全,但可以使用带有静态链接的常量吗 // some header file to be included by multiple .cpp files static const/*expr*/ int CONSTANT = 2; inline in
内联
函数或类中安全地使用命名的const
或constepr
静态
对象?例如,如果常量
位于下面的名称空间
内,则不安全,但可以使用带有静态链接的常量吗
// 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
定义中定义的实体,或在重载解析和部分模板专门化匹配后指同一实体,但名称可指非易失性实体除外
如果对象在D
的所有定义中具有相同的文字类型,并且该对象使用常量表达式初始化,并且该对象未使用odr,并且该对象在D
的所有定义中具有相同的值,则该对象具有内部链接或无链接;及
此用法与“除……和……和……之外”部分中的所有条件都匹配:
- 名称
实际上指的是具有内部链接的非易失性常量
对象常量
- 它在
的所有定义中都具有相同的文本类型f()
- 它是用常量表达式
初始化的李>2
- 不使用odr
- 它在
的所有定义中都具有相同的值f()
“未使用odr”这一点应该是指“未在
f()
中使用odr”——也就是说,如果在程序的其他地方使用了CONSTANT
,它不会中断f()
。至少在C++17中,这不再是一个问题。奇怪的是,类型别名可以解决您的问题:使用CONSTANT=std::integral\u CONSTANT
@Barry从M.M为C++17 I gather删除的引用中删除的“对象未使用odr”?N4606(根据isocpp.org,这是最新的标准草案)仍然有“对象未使用odr”@M.M抱歉idk为什么我一开始认为它会。。等待巴里的response@RyanHainingN4606的日期在该文件之后,该文件与N4606之间的某些文本不同,因此我们需要小心。它的确切含义是“在D
的定义中未使用odr”。