了解命名空间的限定名称查找
Understanding Qualified name lookup for namespace
我想了解命名空间限定名称查找。我正在尝试利用以下
3.4.3.2.2: For a namespace X and name m, the namespace-qualified lookup set S(X,m) is defined as follows: Let S'(X,m) be the set of all
declarations of m in X and the inline namespace set of X (7.3.1). If
S'(X,m) is not empty, S(X,m) is S'(X,m); otherwise, S(X,m) is the
union of S(N_i,m) for all namespaces N_i nominated by using-directives
in X and its inline namespace set.
为标准命名空间中不存在的名称提供回退机制。以下程序举例说明了我设想实现的目标
#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
?
For the second declaration ... S'(fallback, remove_extent)
is non-empty
不,不是:
namespace fallback
{
using namespace std;
}
在这一点之后,S'(fallback, remove_extent)
为空,因此 S
为 S(std, remove_extent)
。
namespace fallback
{
using namespace foo;
}
在这一点之后,S'(fallback, remove_extent)
仍然是空的(即仍然没有直接在[=39中声明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
), 所以编译器正确地告诉你这个名字有歧义。
我想了解命名空间限定名称查找。我正在尝试利用以下
3.4.3.2.2: For a namespace X and name m, the namespace-qualified lookup set S(X,m) is defined as follows: Let S'(X,m) be the set of all declarations of m in X and the inline namespace set of X (7.3.1). If S'(X,m) is not empty, S(X,m) is S'(X,m); otherwise, S(X,m) is the union of S(N_i,m) for all namespaces N_i nominated by using-directives in X and its inline namespace set.
为标准命名空间中不存在的名称提供回退机制。以下程序举例说明了我设想实现的目标
#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
?
For the second declaration ...
S'(fallback, remove_extent)
is non-empty
不,不是:
namespace fallback
{
using namespace std;
}
在这一点之后,S'(fallback, remove_extent)
为空,因此 S
为 S(std, remove_extent)
。
namespace fallback
{
using namespace foo;
}
在这一点之后,S'(fallback, remove_extent)
仍然是空的(即仍然没有直接在[=39中声明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
), 所以编译器正确地告诉你这个名字有歧义。