![](/img/trans.png)
[英]Do inline namespace variables have internal linkage? If not, why does the code below work?
[英]C++ standard: do namespace-scoped constexpr variables have internal linkage?
想象一下,我们有一个包含以下内容的标题foo.h
:
#ifndef FOO_H_
#define FOO_H_
namespace foo {
constexpr std::string_view kSomeString = "blah";
}
#endif // FOO_H_
foo::kSomeString
保证在包含foo.h
任何翻译单元中都有内部链接? 这在C ++ 11和C ++ 17之间有所不同吗?
在草案标准[basic.link] / 3中说
具有命名空间作用域的名称具有内部链接,如果它是非易失性const限定类型的非内联变量的名称,该变量既未显式声明为extern,也未声明为具有外部链接[...]
但我不知道constexpr
算作“const-qualified”。 标准是否在某处说出来?
假设这保证具有内部链接,看起来ODR对此用法没有问题,对吧? (与此答案中的内容形成鲜明对比。)
是的,对象声明的constexpr
意味着对象是const
。 见[dcl.constexpr] / 9 。 是的,这意味着您的示例中的kSomeString
具有内部链接。
我们在这里讨论的ODR违规种类不是kSomeString
本身的定义,而是其他试图使用它的定义。 正是由于内部联系,存在一个问题。 考虑:
void f(const std::string_view &);
inline void g() {
f(foo::kSomeString);
}
如果包含在多个翻译单元中,这是ODR违规,主要是因为每个翻译单元中g
的定义引用了不同的对象。
您对kSomeString
使用是完全有效的。
首先要做的事情; TC解释说,你的对象是const限定的。 它还是文字类型 ,因为它有一个constexpr构造函数。 因此,如果在头文件中定义的函数中使用它,则标准中的以下异常适用(第3.2章):
内联函数可以有多个定义,外部链接(7.1.2),非静态函数模板(14.5.6),(...)在程序中,每个定义出现在不同的翻译单元中,并提供这些定义满足以下要求。 鉴于这样一个名为D的实体在多个翻译单元中定义,那么
- D的每个定义应由相同的令牌序列组成; 和
- 在D的每个定义中,根据3.4查找的相应名称,应指在D的定义中定义的实体,或者在重载决议(13.3)之后和部分模板专业化匹配之后应引用同一实体(14.8) .3), 除了如果对象在D的所有定义中具有相同的文字类型,并且该对象用常量表达式(5.19)初始化,并且值(但不使用对象的地址),并且对象在D的所有定义中具有相同的值 ;
- (......)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.