Вопрос или проблема
Я изучаю пространства имен, но у меня есть два вопроса по этому поводу.
В этом коде:
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int main(){
cout << "Пожалуйста, введите целое число " << endl;
int n1 = 0;
cin >> n1;
cout << "Число равно: " << n1;
return 0;
}
Например, если у меня есть другое имя/идентификатор/сущность с именем ‘cout’, определенное в другом пространстве имен (с другой функциональностью), скажем, в пространстве имен ‘cblue’, я все равно могу использовать ‘cout’, если просто напишу ‘cblue::cout …’ где бы мне это ни понадобилось? Или сейчас я могу использовать только ‘std cout’?
И то же самое в этом коде:
#include <iostream>
using namespace std;
int main(){
cout << "Пожалуйста, введите целое число " << endl;
int n1 = 0;
cin >> n1;
cout << "Число равно: " << n1;
return 0;
}
Я все еще могу использовать ‘cblue cout’, если я пишу ‘cblue::cout …’ или теперь я могу использовать только ‘std cout’?
Заранее спасибо!!!
В первом примере только std::cout
подключается в пространство имен (в данном случае, в глобальную область видимости). Во втором примере вы подключаете все пространство имен std
.
В обоих случаях, ссылаясь на cout
без квалификации, вы будете ссылаться только на std::cout
. Чтобы использовать cblue::cout
, вам нужно использовать квалификацию.
У вас возникнет проблема только в том случае, если вы также используете оператор using
, чтобы подключить cblue::cout
в то же пространство имен, которое подключает std::cout
. В этом случае они будут конфликтовать.
Вы всегда можете использовать cblue::cout
, чтобы ссылаться на cout
внутри пространства имен cblue
, при условии, что он был объявлен ранее.
Когда компилятор видит имя cout
, он выполняет процесс, называемый поиском имени. Если имя предшествует оператору разрешения области (::
), это поиск квалифицированного имени, в противном случае это поиск неквалифицированного имени.
using std::cout;
это объявление using, а using namespace std;
это директива using. Первое вводит имя cout
в текущее пространство и делает его видимым для следующих неквалифицированных поисков. Второе делает все имена из пространства имен std
видимыми в ближайшем окружающем пространстве (в вашем случае, в глобальной области) для следующих неквалифицированных поисков. В любом случае они влияют только на неквалифицированные поиски, и квалифицированные поиски с использованием cblue::cout
не затрагиваются. Обратите внимание, что cblue
в cblue::cout
— это имя, которое обрабатывается в ходе неквалифицированного поиска, и если есть какая-либо неясность в разрешении cblue
само по себе, cblue::cout
все равно может не сработать.
Ответ или решение
Вопрос о том, можно ли использовать идентификаторы вне пространства имен, если вы используете декларацию using namespace
в C++, требует понимания принципов работы пространств имен и механизмов поиска имен в C++.
Основы
Когда вы используете пространство имен, например, стандартное пространство имен std
, вы можете обращаться к элементам этого пространства имен, таким как cout
, cin
и endl
, без префикса std::
, если вы объявили его с помощью using namespace std;
или using std::cout;
.
Рассмотрение примеров
-
Первый пример с
using std::cout;
:
В вашем первом примере используется декларацияusing std::cout;
, что означает, что толькоcout
из пространства именstd
доступен для не квалифицированного использования. Если вы имеете другое пространство имен, напримерcblue
, которое также содержитcout
, вы все равно можете обращаться кcblue::cout
в том же коде, как:cblue::cout << "Some message.";
Декларация
using std::cout;
не влияет на доступ кcblue::cout
, так как использованиеcblue::cout
является квалифицированным обращением. - Второй пример с
using namespace std;
:
Во втором примере, при использованииusing namespace std;
, вы вносите все имена из пространства именstd
в текущее пространство имен, что позволяет вам обращаться кcout
,cin
,endl
и другим элементам без префикса. Тем не менее, как и в первом случае, вы все еще можете использоватьcblue::cout
, поскольку это также квалифицированное обращение:cblue::cout << "Some message from cblue.";
Возможные конфликты
Проблемы могут возникнуть, если у вас есть два идентификатора с одинаковым именем в разных пространствах имен, и вы используете using
для обоих. Например, если вы добавите using cblue::cout;
, то будет наблюдаться конфликт, так как компилятор не сможет определить, какое именно cout
вы имеете в виду. В этом случае вы должны явно указывать, к какому cout
вы обращаетесь (т.е. std::cout
или cblue::cout
).
Заключение
Таким образом, вы можете всегда использовать cblue::cout
, независимо от наличия using namespace std;
или using std::cout;
в вашем коде. Декларации using
влияют только на не квалифицированные обращения к именам. Квалифицированные обращения по-прежнему работают независимо от контекста пространств имен. Однако следует остерегаться конфликтов между идентификаторами, чтобы код оставался читаемым и понятным.