If you’ve seen this program before in beginner tutorials, you’ll know immediately that the material is out of date
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world!\\n";
}
What using namespace std; actually does
using namespace std; is an example of a using-directive. A using directive tells the compiler to consider every name in the std namespace as a candidate during unqualified name lookup.
This is different from a using declaration such as using std::cout;, which exposes a single method.
The directive is broad and all-encompassing; the declaration is precise.
It’s equivalent to carrying your 37-piece toolbag when you only need a screwdriver. You technically have the tool you need but the other 36 tools are now getting in your way.
Problem 1: Naming collisions
The entire purpose of the std being enclosed in a namespace is to prevent naming collisions.
Suppose you write your own swap function:
#include <iostream>
#include <utility>
using namespace std;
void swap(int& a, int& b){
a = b;
b = a; // bug: both end up equal
}
int main(){
int x = 1, y = 2;
swap(x, y);
cout << x << ' ' << y << '\\n';
}
There are now two swap candidates visible without qualification: yours and std::swap. Depending on argument types and overload resolution, the compiler may:
- Pick the one you did not intend
- Reject the call as ambiguous.
Remove using namespace std;, and the problem disappears — swap(x, y) calls your function, and std::swap(x, y) calls the Standard Library’s.
Similarly, if you import the std, you can no longer create a custom vector class since it will clash with std::vector.
Whilst this is a simple example, the chance of naming collisions expands with each new revision of the language.
A program that compiled cleanly under C++17 can break under C++20 because a name you used now collides with a new identifier from the Standard Library.
Problem 2: Reader confusion
Code is read more often than it is written.
When a function is called without the scope resolution operator, the reader has to know whether it came from std, from a third-party library, or from your own code:
sort(items.begin(), items.end()); // std::sort? our own sort?
std::sort(items.begin(), items.end()) answers the question immediately. It is clear what scope the function belongs to.
Problem 3: Increased compilation times
A using directive in a single small main() is mostly harmless. The same line in a header is a serious mistake — every translation unit that includes the header inherits the pollution.
Additionally, using directives cannot be repealed or replaced.
In Conclusion
Take the extra time to type std::. It costs five characters but it will save you a lot of headache!
When a particular method is used repeatedly a using declaration (using std::cout;) can be used, NOT a using directive.