![](/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.