以下代码被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
}
答案 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::f
和B::f
,就好像它们已在全局命名空间中声明一样。声明using A::f
以相同的方式将名称f
引入全局命名空间(尽管它的不同之处在于它实际上使A::f
成为全局命名空间的成员),因此它是多余的就像不合格的查询一样。关键是f
的非限定名称查找在同一声明区域中找到A::f
和B::f
。
<强>解决方案吗
int main()
{
using A::f;
auto n = f(); // no longer ambiguous; finds A::f
}
非限定名称查找查找的第一个位置是main
的块范围,因此它只会找到A::f
,即使A::f
和B::f
都是如果被搜索,则在封闭的命名空间范围内找到。
答案 1 :(得分:2)
因此:
using namespace A;
using namespace B;
两个f
函数都在范围内。它们具有相同的签名,那么您期望发生什么?
这个using指令:
using A::f();
多余。