c++c++11namespaces

What is the relationship between iostream and namespace std?


I am currently using Teach Yourself C++ in 21 Days, Second Edition book to learn about C++ coding, along with Microsoft Visual C++ 2010 Express. At the end of Chapter 1, there is a small exercise about writing and compiling the following code:

#include <iostream>

int main ()
{
    cout << "Hello World!\n";
    return 0;
}

Quite simple, right? However to my surprise the code would not compile, due to this error:

error C2065: 'cout' : undeclared identifier

I began scouring the Web, and soon found some solutions here. Turns out I had to add using namespace std; to my code!

However there was no mention of namespaces in the book, so I figured the book is outdated. (It uses #include <iostream.h> pre-processor directive!) After some more Web research I found a lot of information about namespaces, namespace std, along with some historical background on <iostream.h> and <iostream>, and all this flow of new information is quite confusing to me. (Not to mention all the unnecessary Google results about medical STDs...)

So here are some questions I've got so far:

  1. If I am including the iostream library, why is a namespace needed to find cout? Is there another cout somewhere that could cause a name clash? If someone could provide a diagram for this, that'd be great.

And as a bonus, some historical background:

  1. What exactly was iostream.h before it was changed to iostream?

  2. Did namespace play a part in this change?


Solution

  • All of the standard library definitions are inside the namespace std. That is they are not defined at global scope, so in order to use them you need to qualify them in one of the following way:

    For instance lets take this:

    // declarations
    int global_variable;
    
    namespace n {
    int variable2;
    }
    

    global_variable can be access as it is:

    int x;
    x = global_variable;
    

    But variable2 is not part of the global space, but part of the namespace n.

    int x;
    x = variable2; // error variable2 identifier not found.
    

    So you have to use the fully qualified name:

    int x;
    x = n::variable2;
    

    As a shortcut you can write:

    using namespace n;
    int x;
    x = variable2; // variable2 is searched in current namespace
                   // and in all namespaces brought in with using namespace
                   // Found ONLY in namespace n -> OK
    

    or

    using n::variable2; // this makes any unqualified reference to `variable2`
                        // to be resolved to `n::variable2`
    int x;
    x = variable2;
    

    As for the header files, iostream.h was used by many compilers before there was a standard. When the committee tried to standardize they decided to make the C++ headers extensionless in order to not break compatibility with existing code.