了解名称空间的限定名称查找
我想了解名称空间限定名称查找。我试图利用以下内容了解名称空间的限定名称查找
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
?
对于第二个声明...
S'(fallback, remove_extent)
非空
不,它不是:
namespace fallback
{
using namespace std;
}
这一点后,S'(fallback, remove_extent)
是空的,所以S
是S(std, remove_extent)
。
namespace fallback
{
using namespace foo;
}
这一点后,S'(fallback, remove_extent)
是仍然空(即有还是没有的remove_extent
声明直接fallback
),所以现在S
是S(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
声明),所以编译器正确地告诉您该名称不明确。