C++ namespace and include

duli picture duli · Dec 23, 2008 · Viewed 65.8k times · Source

Why do we need both using namespace and include directives in C++ programs?

For example,

#include <iostream>

using namespace std;

int main() {
 cout << "Hello world";
}

Why is it not enough to just have #include <iostream> or just have using namespace std and get rid of the other?

(I am thinking of an analogy with Java, where import java.net.* will import everything from java.net, you don't need to do anything else.)

Answer

Johannes Schaub - litb picture Johannes Schaub - litb · Dec 23, 2008

using directives and include preprocessor directives are two different things. The include roughly corresponds to the CLASSPATH environment variable of Java, or the -cp option of the java virtual machine.

What it does is making the types known to the compiler. Just including <string> for example will make you able to refer to std::string :

#include <string>
#include <iostream>

int main() {
    std::cout << std::string("hello, i'm a string");
}

Now, using directives are like import in Java. They make names visible in the scope they appear in, so you don't have to fully qualify them anymore. Like in Java, names used must be known before they can be made visible:

#include <string> // CLASSPATH, or -cp
#include <iostream>

// without import in java you would have to type java.lang.String . 
// note it happens that java has a special rule to import java.lang.* 
// automatically. but that doesn't happen for other packages 
// (java.net for example). But for simplicity, i'm just using java.lang here.
using std::string; // import java.lang.String; 
using namespace std; // import java.lang.*;

int main() {
    cout << string("hello, i'm a string");
}

It's bad practice to use a using directive in header files, because that means every other source file that happens to include it will see those names using unqualified name lookup. Unlike in Java, where you only make names visible to the package the import line appears in, In C++ it can affect the whole program, if they include that file directly or indirectly.

Be careful when doing it at global scope even in implementation files. Better to use them as local as possible. For namespace std, i never use that. I, and many other people, just always write std:: in front of names. But if you happen to do it, do it like this:

#include <string>
#include <iostream>

int main() {
    using namespace std;
    cout << string("hello, i'm a string");
}

For what namespaces are and why you need them, please read the proposal Bjarne Stroustrup gave 1993 for adding them to the upcoming C++ Standard. It's well written:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0262.pdf