[英]About the ambiguity of using a name vs using a namespace when doing unqualified calls
我知道這會模棱兩可
#include <boost/hana/fwd/equal.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <vector>
int main() {
std::vector<int> v{1,2,3};
using namespace boost::hana;
using namespace ranges;
equal(v, v);
}
因為boost::hana
和ranges
命名空間是equal
的。
但是,我認為這也很模棱兩可:
#include <boost/hana/fwd/equal.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <vector>
int main() {
std::vector<int> v{1,2,3};
using namespace boost::hana;
using ranges::equal;
equal(v, v);
}
但根據GCC 和 Clang ,情況並非如此。
這是為什么?
讓我們看看示例中的第二個代碼段是如何工作的,因為您已經知道第一個代碼段產生不明確錯誤的原因。
來自使用指令的文檔:
僅在命名空間 scope 和塊 scope 中允許使用指令。從使用指令之后的任何名稱的非限定名稱查找的角度來看,直到它出現的 scope 結束,命名空間名稱中的每個名稱都是可見,就好像它是在最近的包含 using-directive 和 namespace-name 的封閉命名空間中聲明的一樣。
using-directive 不會將任何名稱添加到它出現的聲明區域(與 using-declaration 不同),因此不會阻止聲明相同的名稱。
這意味着using directive
不會在聲明區域中引入名稱(在您的示例中它只是main
的 function),而是引入最近的封閉命名空間(在您的示例中是global namespace
)。
現在,當調用表達式equal(v, v);
發生非限定查找時; 搜索從遇到調用表達式的點向上進行,並找到由於聲明區域(即main
)中的using declaration
而引入的equal
版本,因此搜索停止。 所以這個已經找到的版本被使用。
一個人為的例子可能有助於澄清情況:
#include <iostream>
namespace X
{
void func(){std::cout<<"X version called"<<std::endl;}
}
namespace Y
{
void func(){std::cout<<"Y version called"<<std::endl;};
}
int main()
{
using namespace X;
using Y::func;
func(); //calls Y version
return 0;
}
您的示例中的代碼段 1 也可以根據上面引用的語句來理解。 特別是,您在片段 1 中遇到了不明確的錯誤,因為命名空間ranges
和boost::hana
都有一個 function 被稱為equal
,它們的排名相同。 因此,當調用表達式equal(v,v)
發生非限定名稱查找時,搜索開始並從遇到調用表達式的點向上查找,並找到名為equal
的函數,由於這兩個原因,它們在全局名稱范圍中可見名稱空間。 此外,由於兩者排名相同,我們得到了提到的模棱兩可的錯誤。
一個人為的例子可能有助於澄清情況:
#include <iostream>
namespace X
{
void func(int)
{
std::cout<<"X version func called"<<std::endl;
}
void foo()
{
std::cout<<"X version foo called"<<std::endl;
}
}
namespace Y
{
void func(double)
{
std::cout<<"Y version func called"<<std::endl;
}
void foo()
{
std::cout<<"Y version foo called"<<std::endl;
}
}
int main()
{
using namespace X ;
using namespace Y;
func(3); //calls X's func
func(5.5);//calls Y's func
foo();//fails due to ambiguity
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.