S.T.A.L.K.E.R. S.T.A.L.K.E.R. - 1 month ago 9
C++ Question

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?


Answer

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:

  • std::cout
  • using namespace std
  • using std::cout

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 not to break compatibility with existing code.