我一直在阅读Exceptional C++ by Herb Sutter
。到达Item 32
我找到了以下
namespace A
{
struct X;
struct Y;
void f( int );
void g( X );
}
namespace B
{
void f( int i )
{
f( i ); // which f()?
}
}
这个f()调用自身,具有无限递归。原因是唯一可见的f()是B :: f()本身。
还有另一个带有签名f(int)的函数,即命名空间A中的函数。如果B使用命名空间A写出“”或“使用A :: f;”,则A当查找f(int)时,:: f(int)将作为候选者可见,并且f(i)调用在A :: f(int)和B :: f(int)之间将是不明确的。由于B没有将A :: f(int)带入范围,因此只能考虑B :: f(int),因此调用明确地解析为B :: f(int)。
但是当我做了以下事情时......
namespace A
{
struct X;
struct Y;
void f( int );
void g( X );
}
namespace B
{
using namespace A;
void f( int i )
{
f( i ); // No error, why?
}
}
这意味着Herb Sutter完全错了吗?如果不是为什么我不会收到错误?
答案 0 :(得分:18)
使用声明(using A::f
)和使用指令(using namespace A
)之间存在细微差别。
using声明在使用声明的范围中引入了一个名称,因此using A::f
在f
的定义中调用B::f(int)
不明确。
使用定义使命名空间的成员在使用它的作用域中可见,但它们出现,就好像该名称来自引入的命名空间的最近公共作用域和其中的名称空间使用了using指令。这意味着在这种情况下using namespace A;
会使另一个f
看起来好像是在全局范围内声明,但它仍然被B::f(int)
隐藏。
(ISO / IEC / BS 14882:2003 7.3.4 [namespace.udir] / 1适用于所有标准爱好者。)