Несоответствие неоднозначности поиска имени

Я пытаюсь понять, почему эта программа не дает неоднозначность поиска имени для меня:

namespace X { int i = 1; }

namespace Q {    
    namespace P {        
        int i = 2;
        using namespace X;
    }

    using namespace P;

    int l = i;
}

int main() {}

Если мы изменим это так, мы получим неоднозначность поиска имени:

namespace X { int i = 1; }

namespace P {        
    int i = 2;
    using namespace X;
}

using namespace P;

int l = i;

int main() {}

Единственное изменение, которое я сделал здесь, - это удалить пространство имен Q и поместить его содержимое в глобальное пространство имен.

Я пробовал с 3 разных компиляторов:

Все дают результаты, указанные в этом письме, и я пытаюсь выяснить, почему.

Может кто-нибудь объяснить поведение с точки зрения стандарта C++? Я не понимаю этого.

1 ответ

Решение

В первой программе используется переменная i определяется в пространстве имен P, потому что директива using

using namespace X;

размещает объявления X в глобальном пространстве имен (общее пространство имен для X и P). Таким образом, декларация i в P (точнее в Q из-за другой директивы using) скрывает объявление X::i в глобальном пространстве имен.

Из стандарта C++ (3.4.1 Безусловный поиск имени)

2 Объявления из пространства имен, назначенного директивой using, становятся видимыми в пространстве имен, включающем директиву using; см. 7.3.4.

Итак, мы имеем для первой программы

namespace X { int i = 1; }

namespace Q {    
    namespace P {        
        int i = 2;
        using namespace X; // 1
    }

    using namespace P; // 2

    int l = i;
}

что включающее пространство имен для использования директивы #1 является глобальным пространством имен, а включающее пространство имен для использования директивы #2 является пространством имен Q.

Во второй программе оба определения i помещаются в глобальное пространство имен из-за этих двух директив using

//...
using namespace X;
//...
using namespace P;
Другие вопросы по тегам