2015-02-11 86 views
0

我想了解名稱空間限定名稱查找。我試圖利用以下內容瞭解名稱空間的限定名稱查找

3.4.3.2.2對於名稱空間X和名稱m,命名空間限定查找集合S(X,m)定義如下:令S'(X, m)是X的所有 聲明m的集合,以及X(7.3.1)的內聯名稱空間集合。如果 S'(X,m)不爲空,則S(X,m)爲S'(X,m)。否則,S(X,m)是所有命名空間N_i的S(N_i,m)的聯合,其使用X中的使用指令 及其內聯命名空間集合提名。

爲名稱提供回退機制,如果它不存在於標準名稱空間中。下面的程序舉例說明了什麼,我設想實現

#include <type_traits> 
namespace foo 
{ 
    template<class Ty> 
    struct remove_extent 
     { 
     typedef Ty type; 
     }; 
} 
namespace fallback 
{ 
    using namespace std; 
} 
namespace fallback 
{ 
    using namespace foo; 
} 
template<typename Ty> 
struct Bar 
{ 
    typename fallback::remove_extent<Ty>::type var; 
}; 
int main() 
{ 
    Bar<int[]> var; 
} 

對於第一個聲明

namespace fallback 
{ 
    using namespace std; 
} 

S'(fallback, remove_extent)是空集,所以S(fallback, remove_extent)S(std, remove_extent).

工會對於第二個聲明

namespace fallback 
{ 
    using namespace foo; 
} 

S'(fallback, remove_extent)非空的,所以S(fallback, remove_extent) = S'(fallback, remove_extent) = S(std, remove_extent)

但我的編譯器認爲否則並抱怨

1>source.cpp(21): error C2872: 'remove_extent' : ambiguous symbol 
1>   could be 'source.cpp(6) : foo::remove_extent' 
1>   or  'c:\program files (x86)\microsoft visual studio 11.0\vc\include\type_traits(331) : std::remove_extent' 

所以很明顯我的理解是錯誤的。爲什麼編譯器包含來自foo的名稱remove_extent

回答

4

對於第二個聲明... S'(fallback, remove_extent)非空

不,它不是:

namespace fallback 
{ 
    using namespace std; 
} 

這一點後,S'(fallback, remove_extent)是空的,所以SS(std, remove_extent)

namespace fallback 
{ 
    using namespace foo; 
} 

這一點後,S'(fallback, remove_extent)仍然空(即有還是沒有的remove_extent聲明直接fallback),所以現在SS(std, remove_extent)S(foo, remove_extent)工會。

template<typename Ty> 
struct Bar 
{ 
    typename fallback::remove_extent<Ty>::type var; 
}; 

當我們到了這一點,也有fallback命名remove_extent兩個實體(一個來自std,一個來自foo,無論是直接在fallback聲明),所以編譯器正確地告訴您該名稱不明確。