2015-02-11 64 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声明),所以编译器正确地告诉您该名称不明确。

相关问题