As I was learning C++ I bumped into a question that wouldn't let me be: "Why do i need to include "using namespace std" in my code to be able to write or read if i already got iostream?", because I've been told that "cin/cout" are already defind in iostream library, but I noticed that if I write one of these lines alone it will give a compilation error. And ,therefore, what's the relation between iostream and "std" namespace?
Libraries and namespaces are related by convention.
By convention, the symbols that a library provides to the programmer-user are contained in a namespace. This organizes things, and there are some higher level language features (ADL) that mean code in a namespace behaves differently than code outside of it.
When you type using namespace std;
you tell the compiler "when you run into a symbol, also look into std
to find if you can determine what it is". It is generally a really really bad idea to do this at "file" scope; doing it within a single short function is usable, but any more than that can lead to really tricky bugs.
The standard, professional way to interact with namespace std
is to prefix your symbols with the namespace:
std::cout << "Hello world\n";
rather than
using namespace std;
cout << "Hello world\n";
and definitely never:
using namespace std;
int main() {
cout << "Hello world\n";
}
you can also grab single symbols, which isn't as bad as importing an entire namespace:
using std::cout;
cout << "Hello world\n";
but should also be avoided at "file" scope.
#include <iostream>
this includes the header file named iostream
from the system search path. iostream
is part of the standard library. By convention (and the C++ standard), the symbols that iostream
provides your program with are located within namespace std
.
By putting symbols in a namespace, you avoid conflict with your code. There are many, many symbols in std
, and if #include <iostream>
shoved some unknown number of symbols into your global namespace, you could easily get errors or the wrong function called in unexpected ways.
std::cout
and using namespace std; cout
and using std::cout
are all ways to tell the compiler in what namespace to find the symbol cout
.
#include <iostream>
includes cout
in namespace std
; without it, your code is unaware of its existence.
C++ developed from C, and C has a textual inclusion model. #include
actually takes the content of the file iostream
and copy/pastes it into your file. Your compiler then reads that extended file and finds the symbols in <iostream>
.
Because this textual inclusion could shove a LOT of stuff, having it isolated to a namespace
prevents problems for you, the programmer.
Recently, C++ has added modules. Modules are an alternative to #include
directives, in that it directly grabs symbols from a library and injects it into your code without a huge copy paste.
In modules, namespaces are still not directly connected to the module. You can
import std;
or
import std.iostream;
and that will just import the std
library symbols, still in namespace std
, into your code. (the C++ standard added modules, but did not modularize the std library yet, so those names above are speculation).
The symbol lookup is not directly connected to the symbol import.
This lets symbol import be done in large chunks, while lookup be done more carefully.