using namespace std — что это
Всё из стандартной библиотеки C++ — cout, cin, string, vector, sort — лежит в пространстве имён std. Полное имя каждой такой вещи начинается с std::: std::cout, std::vector. Строка
using namespace std;разрешает писать эти имена без приставки: cout вместо std::cout. Две программы ниже равнозначны:
#include <iostream>
#include <string>
int main() {
std::string name = "Anna";
std::cout << "Hi, " << name << "\n";
return 0;
}Hi, Anna#include <iostream>
#include <string>
using namespace std;
int main() {
string name = "Anna";
cout << "Hi, " << name << "\n";
return 0;
}Hi, AnnaЗачем вообще пространства имён
Чтобы имена из разных библиотек не сталкивались. В стандартной библиотеке сотни имён: count, max, min, distance, next, prev, size, data, left, right… Если бы все они были «просто так», их нельзя было бы взять для своих переменных и функций. std:: отделяет имена стандартной библиотеки от ваших.
Когда using namespace std мешает
using namespace std; снова сваливает все эти имена в одну кучу с вашими. Если назвать свою глобальную переменную или функцию так же, как что-то из std, компилятор не поймёт, какую из них имели в виду:
#include <iostream>
#include <algorithm>
using namespace std;
int count = 0; // глобальная переменная с именем как у std::count
void add() {
count++; // ошибка: какой count?
}error: reference to 'count' is ambiguousРешение — переименовать свою переменную (cnt, total) или убрать using namespace std; и писать std::. Внутри функций такая проблема почти не возникает: локальная переменная count закрывает собой std::count.
Так можно или нет?
- В учебных программах и на олимпиадах — можно и принято. Программа из одного файла, все имена на виду, а писать
std::перед каждымcoutутомительно. - В заголовочных файлах (
.h) — нельзя. Заголовок подключается в чужие файлы, иusing namespace std;попадёт в каждый из них, вызывая конфликты имён там, где их никто не ждёт. - В больших проектах обычно пишут
std::явно или подключают только нужные имена:
#include <iostream>
using std::cout;
int main() {
cout << "only cout without std::\n";
return 0;
}only cout without std::using std::cout; открывает одно имя, а не всё пространство std — конфликтов меньше.