Подтвердить что ты не робот

Исключительный С++ [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?
     }
 }

Это означает, что у Херба Саттера все неправильно? Если нет, то почему я не получаю сообщение об ошибке?

4b9b3361

Ответ 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 для всех стандартных наркоманов.)