下面的代碼(令人吃驚地)不與任一g++
或clang++
編譯由於不明確的呼叫BuildStream
一個輸入。導入單個類成命名空間<code>bar::Rectangle</code>作爲實例<code>bar::BuildStream</code>時似乎要求有沒有功能名稱衝突的命名空間之間
#include <iostream>
#include <sstream>
namespace foo {
struct Rectangle { double height, width; };
std::ostream& operator<<(std::ostream& os, const Rectangle& a) { return os; }
inline void BuildStream(std::ostringstream& os) { }
template<typename T, typename... Args>
void BuildStream
(std::ostringstream& os, const T& item, const Args& ...args) {
os << item;
BuildStream(os, args...);
}
} // namespace foo
namespace bar {
inline void BuildStream(std::ostringstream& os) { }
template<typename T, typename... Args>
void BuildStream
(std::ostringstream& os, const T& item, const Args& ...args) {
os << item;
BuildStream(os, args...);
}
using Rectangle = foo::Rectangle;
} // namespace bar
int main(int argc, char* argv[]) {
std::ostringstream os;
bar::BuildStream(os, 1, 2);
bar::BuildStream(os, bar::Rectangle(), bar::Rectangle());
return 0;
}
的不確定性似乎在暗示,一般來說,如果一個類從命名空間foo
導入命名空間bar
,則必須格外小心,以確保bar
沒有功能相同功能foo
名。這明顯引發了名稱空間的一些好處。是否有避免這種歧義的更細緻的方法?
上下文是foo
是大型庫的名稱空間,而bar
是消費者項目的名稱空間(並且在實踐中出現此問題)。
你會得到同樣的錯誤,如果你:1.刪除「使用」,2通行證「富::矩形」從主。這是由於[參數依賴查找](http://stackoverflow.com/questions/8111677/what-is-argument-dependent-lookup-aka-adl-or-koenig-lookup)。也明確地從模板函數調用bar :: BuildStream()將修復編譯錯誤。 –
感謝您提供參數相關查詢的鏈接;這是解釋這種(有點不幸的)行爲的恰當的細微討論。 –