Вопрос или проблема
Я начал изучать c++ на www.learncpp.com, и здесь я читаю, что нет проблем с определением собственных объектов с именами ‘cout’ или ‘cin’, поскольку C++ переместил все функции в стандартной библиотеке в пространство имен std. Однако я пытаюсь определить глобальную переменную с именем cout и затем использовать ее в main, но компилятор жалуется, что ссылка неоднозначна. И я не понимаю, почему. Можете ли вы объяснить, почему у меня эта ошибка?!
Вот код:
#include <iostream>
using namespace std;
int getInteger();
int cout;
int main()
{
int x{ getInteger() };
int y{ getInteger() };
cout = 20;
std::cout << x << " + " << y << " равно " << x + y << '\n';
return 0;
}
int getInteger()
{
std::cout << "Введите целое число: ";
int x{};
std::cin >> x;
return x;
}
Ошибка:
||=== Сборка: Debug в Chapter2_8 (компилятор: GNU GCC Compiler) ===|
C:\CBProjects\Chapter2_8\main.cpp||В функции 'int main()':|
C:\CBProjects\Chapter2_8\main.cpp|13|ошибка: ссылка на 'cout' неоднозначна|
C:\Program Files\CodeBlocks\MinGW\lib\gcc\x86_64-w64-mingw32\8.1.0\include\c++\iostream|61|заметка: кандидаты: 'std::ostream std::cout'|
C:\CBProjects\Chapter2_8\main.cpp|6|заметка: 'int cout'|
||=== Сборка завершилась с ошибкой: 1 ошибка(ий), 0 предупреждений(ий) (0 минут(ы), 0 секунд(ы)) ===|
Чтение дальше. Глава “Использование пространства имен std (и почему этого следует избегать)” объясняет проблему с using namespace std;
и почему это не позволяет вам использовать имена из std
пространства имен больше.
Добавив using namespace std;
, вы перенесли все имена из пространства имен std
в глобальное пространство имен, и теперь компилятор не может различить между вашим int cout
, который вы объявили в глобальном пространстве имен, и std::ostream cout
, который также находится в глобальном пространстве имен из-за using namespace std;
.
Ответ или решение
Проблема, с которой вы столкнулись, связана с амфиболией (неоднозначностью) ссылки на имя cout
. Давайте разберемся, что происходит в вашем коде и почему возникает эта ошибка.
Причина ошибки
Когда вы используете директиву using namespace std;
, все имена из пространства имен std
становятся доступны в глобальном пространстве имен. Это означает, что вы можете называть свои переменные так же, как и стандартные, определенные в библиотеке C++, например, cout
.
В вашем коде вы объявили переменную cout
типа int
в глобальной области видимости:
int cout;
При этом вы также используете стандартный объект std::cout
, который представляет собой поток вывода:
std::cout << ...;
Когда компилятор сталкивается с именем cout
в функции main
, он не может определить, о какой именно переменной идет речь: о вашем int cout
или стандартном std::ostream cout
. Это и вызывает ошибку "ссылка на ‘cout’ неоднозначна".
Как исправить ошибку
Чтобы избежать такой неоднозначности, вы можете либо:
-
Избегать использования
using namespace std;
. Вместо этого вы можете явно указывать пространство имен при каждом обращении к стандартным именам. Например:#include <iostream> int getInteger(); int myCout; // Переименуйте переменную, чтобы избежать конфликта int main() { int x{ getInteger() }; int y{ getInteger() }; myCout = 20; // Используйте новое имя std::cout << x << " + " << y << " is " << x + y << '\n'; return 0; } int getInteger() { std::cout << "Enter an integer: "; int x{}; std::cin >> x; return x; }
-
Если вы все же хотите использовать
using namespace std;
, то просто переименуйте вашу переменнуюcout
во что-то другое, например,myCout
или любой другой идентификатор, чтобы избежать конфликта имен:int myCout; // Переименование
Заключение
Наилучший подход для грамотной организации кода — это избегать использования using namespace std;
в заголовочных файлах и крупных проектах, так как это может привести к конфликтам имен и осложнениям с поддержкой кода. Всегда лучше явно указывать пространство имен, чтобы избежать неоднозначностей и улучшить читаемость кода.