2016-01-18 4 views
0

Это может показаться очевидным, почему пространство имена должны быть уникальными в пределах своей сферы:Имя пространства имен должно быть уникальным для области видимости. Зачем?

namespace test{} 

int test = 10; //error 'int test' redeclared as different kind of symbol 

Но, похоже, что компилятор способен различать ли имя ссылается на переменный или пространство имен:

#include <iostream> 

namespace test{ 
    int x = 2; 
} 

int main(){ 

    int test = 5; 

    using namespace test; //I was expecting an error to occur here. 
    std::cout << test::x << std::endl; 

} 

В этом коде компилятор (g ++ 5.2.0) не поднимает шум по поводу директивы using test или использует оператор области видимости на test, несмотря на то, что существует локальная переменная с именем test. Контекст, по-видимому, дает понять, что он ссылается на пространство имен и, следовательно, на поиск имени (если происходит поиск по имени) пропускает минус int переменная test, чтобы найти пространство имен в глобальной области.

Следовательно, почему первым примером является проблема, если компилятор может различать использование пространств имен? Есть ли контекст, в котором выражение может ссылаться либо на переменную, либо на пространство имен?

ответ

3

Два разных одноименных объявления в той же области - вот что вызывает проблему.

Во втором примере пространство имен находится во внешней области видимости и определение переменной во внутренней области. Это дает однозначный способ решить между ними. По-прежнему возможно, чтобы создать двусмысленность в нескольких случаях, но по крайней мере сами определения не сталкиваются.

В вашем первом примере может определить язык, допускающий неоднозначные определения в одном и том же объеме, если каждый из них использовался только так, чтобы это не было двусмысленным. Однако разработчики C++ решили избежать этого (и IMO, так или иначе, - если что-либо, C++ уже допускает слишком много, что ставит большинство людей как неоднозначное, хотя правила четко указывают, что должен делать компилятор).

Что касается второго примера в состоянии найти namespace, даже если он определен на внешнюю области, где он затененная (скрытый) переменное определение: это правда, но вы только позволили определить пространство имен вне любой функции, поэтому в директиве using (ваш using namespace ...) компилятор никогда даже не видит внутри функции, чтобы увидеть определение переменной, потому что вы не могли определить пространство имен там, независимо.

+0

Я думаю, что его вопрос связан с тем, что 'использование теста пространства имен' вызывает 'test', чтобы иметь два разных значения в одной области, но неясно, какая разница между этой ситуацией и той, которая действительно вызывает ошибка –

+0

Поиск * using-directive * s просто игнорирует все имена без имен (http://eel.is/c++draft/basic.lookup.udir). –