为什么`使用A :: f`不能按预期工作?

时间:2014-06-20 03:46:57

标签: c++ namespaces using

以下代码被VC ++和clang拒绝。

为什么using A::f无法按预期工作?

有没有办法在给定的名称空间中隐藏某些名称?

namespace A
{
    int f()
    {
        return 1;
    }
};

namespace B
{
    int f()
    {
        return 2;
    }
};

using namespace A;
using namespace B;

using A::f; // I want to hide B::f and only use A::f, how to do?

int main()
{
    auto n = f(); // error : call to 'f' is ambiguous
}

2 个答案:

答案 0 :(得分:4)

该标准规定了using指令的解释。强调我的:

  

using-directive 指定指定命名空间中的名称可以在范围内使用     using-directive 出现在 using-directive 之后。 在非限定名称查找(3.4.1)期间,将显示名称     好像它们是在最近的封闭命名空间中声明的,它包含 using-directive 和    指定的命名空间。 [注意:在此上下文中,“包含”表示“直接或间接包含”。 - 结束             注意]

(C ++11§7.3.4/ 2)

因此,在

之后
using namespace A;
using namespace B;

对名称f的非限定性查找会发现A::fB::f ,就好像它们已在全局命名空间中声明一样。声明using A::f以相同的方式将名称f引入全局命名空间(尽管它的不同之处在于它实际上使A::f成为全局命名空间的成员),因此它是多余的就像不合格的查询一样。关键是f的非限定名称查找在同一声明区域中找到A::fB::f

<强>解决方案吗

int main()
{
    using A::f;
    auto n = f(); // no longer ambiguous; finds A::f
}

非限定名称查找查找的第一个位置是main的块范围,因此它只会找到A::f,即使A::fB::f都是如果被搜索,则在封闭的命名空间范围内找到。

答案 1 :(得分:2)

因此:

using namespace A;
using namespace B;

两个f函数都在范围内。它们具有相同的签名,那么您期望发生什么?

这个using指令:

using A::f();

多余。