I have been reading Exceptional C++ by Herb Sutter. On reaching Item 32
I found the following
namespace A
{
struct X;
struct Y;
void f( int );
void g( X );
}
namespace B
{
void f( int i )
{
f( i ); // which f()?
}
}
This f() calls itself, with infinite recursion. The reason is that the only visible f() is B::f() itself.
There is another function with signature f(int), namely the one in namespace A. If B had written “using namespace A;” or “using A::f;”, then A::f(int) would have been visible as a candidate when looking up f(int), and the f(i) call would have been ambiguous between A::f(int) and B::f(int). Since B did not bring A::f(int) into scope, however, only B::f(int) can be considered, so the call unambiguously resolves to B::f(int).
But when I did the following..
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?
}
}
That means Herb Sutter has got it all wrong? If not why dont I get an error?
There’s a subtle difference between a using declaration (
using A::f) and a using directive (using namespace A).A using declaration introduces a name into the scope in which it is used so
using A::fmakes the call tofin the definition ofB::f(int)ambiguous.A using definition makes members of the namespace visible in the scope in which it is used, but they appear as if the name comes from the nearest common scope of the namespace introduced and the namespace in which the using directive was used. This means that
using namespace A;in this case make the otherfappear as if it was declared at the global scope but it is still hidden byB::f(int).(ISO/IEC/BS 14882:2003 7.3.4 [namespace.udir] / 1 for all the standard junkies.)