質問

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?

役に立ちましたか?

解決

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.

他のヒント

Because this line starts with #, it is called a "preprocessor directive". The preprocessor reads your program before it is compiled and only executes those lines beginning with #. The preprocessor sets up your source code for the compiler.

The #include directive causes the preprocessor to include the contents of another file into the program. The iostream file contains code that allows a C++ program to display output to the screen and take input from the keyboard. The iostream files are included in the program at the point the #include directive appears. The iostream is called a header file and appears at the top or head of the program.

using namespace std;

C++ uses namespaces to organize names or program entities. It declares that the program will be assessing entities who are part of the namespace called "std." Every name created by the iostream file is part of that namespace.

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?

It is needed because the C++ standard requires that cout be inside the std namespace. There could be a clashing cout, but not in the standard library (e.g. your own code, or some third party library.)

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

It could be anything, because it is not part of the standard, but it was the name of a pre-standardization header which formed the basis for iostream. Usually, it declared all names in the global namespace, so it is likely that the example you are looking at was written pre-standardization.

2.Did namespace play a part in this change?

This question is unclear. The keyword namespace may be used inside implementations, and it is used to declare and define data, functions, types etc. inside a namespace. So it did have some part in this change.

namespace foo
{
  void bar();  // declares foo::bar
}

In C++, you can logically group identifiers into namespaces. cout stream is inside namespace std. You can use it in 3 ways.

  1. Write using namespace std at top and use cout as you did.
  2. Write using std::cout at top and use cout as you did.
  3. Use std::cout instead of cout

Thanks to @bolov ..to understand the point referring this standard, this is the declaration:

#include <ios>
#include <streambuf>
#include <istream>
#include <ostream>

namespace std 
{
    extern istream cin;
    extern ostream cout;
    extern ostream cerr;
    extern ostream clog;

    extern wistream wcin;
    extern wostream wcout;
    extern wostream wcerr;
    extern wostream wclog;
}

With new version of c++ namespace was included. iostream contains all the declarations for input and output. Namespace std is used to tell that we are using cout and cin which were part of std namespace. You can create your own variables named cout and cin in your own namespace.

I had the same question as you. I am just going to teach you in laymen terms.

Imagine that you need a pencil which is placed in a drawer which is present in your bedroom. So you need to enter in your room to access your pencil. Here room is iostream. After you entered your room, you need to open the drawer and access the pencil. Here drawer is namespace and pencil is cin/cout.

Reference:- https://en.wikiversity.org/wiki/C%2B%2B/Introduction

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top