Исключительный С++ [Bug]?
Я читал 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 scope (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?
}
}
Это означает, что у Херба Саттера все неправильно? Если нет, то почему я не получаю сообщение об ошибке?
Ответы
Ответ 1
Существует тонкая разница между объявлением using (using A::f
) и директивой using (using namespace A
).
Использование с помощью объявления вводит имя в область, в которой оно используется, поэтому using A::f
делает вызов f
в определении B::f(int)
неоднозначным.
Использование с использованием определения делает члены пространства имен видимыми в области, в которой он используется, но они выглядят так, как будто имя происходит из ближайшей общей области вложенного пространства имен и пространства имен, в котором использовалась директива use. Это означает, что using namespace A;
в этом случае сделает другой f
отображаемым, как если бы он был объявлен в глобальной области видимости, но он по-прежнему скрыт B::f(int)
.
(ISO/IEC/BS 14882: 2003 7.3.4 [namespace.udir]/1 для всех стандартных наркоманов.)