Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;标准:命名空间范围的constexpr变量是否具有内部链接?_C++_C++11_Language Lawyer_C++17_Linkage - Fatal编程技术网

C++ C++;标准:命名空间范围的constexpr变量是否具有内部链接?

C++ C++;标准:命名空间范围的constexpr变量是否具有内部链接?,c++,c++11,language-lawyer,c++17,linkage,C++,C++11,Language Lawyer,C++17,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之间是否有所不同 标准草案中说 如果名称空间范围为[…]的名称是非易失性常量限定类型的非内联变量,且该变量

假设我们有一个包含以下内容的标题
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之间是否有所不同

标准草案中说

如果名称空间范围为[…]的名称是非易失性常量限定类型的非内联变量,且该变量既没有显式声明为extern,也没有先前声明为具有外部链接[…],则该名称具有内部链接

但我不知道
constexpr
是否算作“const-qualified”。标准中有这样的规定吗


假设保证有内部链接,ODR在这种情况下似乎不会有问题,对吗?(与中所述相反。)

是的,对象声明上的
constexpr
表示对象是
const
。看见是的,这意味着在您的示例中,
kSomeString
具有内部链接

我们在这里讨论的ODR违规种类不是
kSomeString
本身的定义,而是试图使用它的其他定义。而问题恰恰是因为内部联系。考虑:

void f(const std::string_view &);

inline void g() { 
    f(foo::kSomeString); 
}

如果包含在多个翻译单元中,这就是ODR冲突,主要是因为每个翻译单元中的
g
的定义引用了不同的对象。

您对
kSomeString
的使用完全有效

第一件事优先;正如T.C.所解释的,您的对象是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的所有定义中具有相同的值
  • (……)

是的,声明中的
constepr
意味着C++11中的
const
。在C++14及更高版本中,它仅在变量上暗示
const
,而不是在成员函数上。谢谢!你知道标准的哪一部分是这样写的吗?谢谢!您的ODR问题示例很有意义-
g
在每个翻译单元中都不相同。可能存在不涉及内联函数的问题吗?@jacobsa:使用非类型参数的模板是另一个明显的例子。@t.C.,恐怕我不太同意你的看法,请看我的答案。“使用的是对象的值(而不是地址)”。绑定引用使用它的地址。@T.C.你是对的,但我没有错:)。我不鼓励接受它的地址。我同意您的特殊使用是一个陷阱,但我想指出的是,在共享定义中使用这样的对象通常是正确的。