[英]What are the name resolution rules in C++ namespaces?
如何在 C++ 命名空間中解析名稱?
我對以多種不同方式提供名稱的情況特別感興趣,例如通過父命名空間和using namespace
。
拿這段代碼:
namespace ns1 {
static auto str = "ns1::str";
}
namespace ns2 {
static auto str = "ns2::str";
namespace sub {
using namespace ns1;
auto f() { return str; }
}
}
使用我的編譯器, ns2::sub::f()
返回"ns2::str"
。 我希望它返回"ns1::str"
,因為using namespace ns1
出現在ns2::sub
中。
現在這件作品:
static auto str = "str";
namespace ns1 {
static auto str = "ns1::str";
}
namespace ns2 {
using namespace ns1;
auto f() { return str; }
}
我希望它的行為與前一個案例一樣。 相反,它不編譯:
錯誤:對“str”的引用不明確
這背后的邏輯是什么?
使用指令要記住的規則如下
[命名空間.udir]
2 using-directive 指定指定命名空間中的名稱可以在 using-directive 出現在 using-directive 之后的 scope 中使用。 在非限定名稱查找 ([basic.lookup.unqual]) 期間,名稱看起來好像它們是在最近的封閉命名空間中聲明的,其中包含使用指令和指定命名空間。 [注:在此上下文中,“包含”是指“直接或間接包含”。 ——尾注]
3 using-directive 不會將任何成員添加到它出現的聲明區域。
第 3 段確保在嘗試名稱查找之前不會出錯。 它不添加聲明,只要不通過非限定名稱查找來查找str
,我們就不會發生沖突。 而第 2 段告訴我們名稱的邏輯布局。 我們可以將其應用於您的兩個示例。
包含using namespace ns1;
命名空間ns1
本身就是全局命名空間。 所以名稱ns1::str
的行為就像我們寫的一樣
static auto str = "ns1::str"; namespace ns2 { static auto str = "ns2::str"; namespace sub { auto f() { return str; } } }
因此,名稱查找只會找到ns2::str
,因為它會隱藏任何str
並封閉命名空間(這是上面代碼中的“as-if”情況)。
同樣,最近的封閉命名空間是全局命名空間。 但這一次,我們得到的布局不同
static auto str = "str"; // This is the one declared static auto str = "ns1::str"; // This is the one "as-if" made available namespace ns2 { auto f() { return str; } }
顯然,上面的“等效”代碼片段不是有效的,聲明將是相互沖突的。 但這是沖突根源的例證。 來自 scope 的名稱存在沖突。 所以不合格的名稱查找失敗。
在沒有使用指令的情況下,非限定名稱查找的行為相當直觀。 范圍從內到外查找,直到找到名稱的聲明。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.