【问题标题】:Understanding Qualified name lookup for namespace了解命名空间的限定名称查找
【发布时间】:2015-04-11 18:01:50
【问题描述】:

我想了解命名空间限定名称查找。我正在尝试利用以下

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

【问题讨论】:

    标签: c++ c++11 namespaces language-lawyer


    【解决方案1】:

    对于第二个声明...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),所以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 中声明),所以编译器正确地告诉你名称不明确。

    【讨论】:

      猜你喜欢
      • 2014-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      相关资源
      最近更新 更多