web-dev-qa-db-fra.com

Quelle est la relation entre iostream et namespace std?

J'utilise actuellement Teach Yourself C++ in 21 Days, Deuxième édition book pour en savoir plus sur le codage C++, ainsi que sur Microsoft Visual C++ 2010 Express. À la fin du chapitre 1, vous trouverez un petit exercice sur l’écriture et la compilation du code suivant:

#include <iostream>

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

Assez simple, non? Cependant, à ma grande surprise, le code n'a pas été compilé, à cause de cette erreur:

erreur C2065: 'cout': identifiant non déclaré

J'ai commencé à parcourir le Web et j'ai rapidement trouvé des solutions ici . Il s'est avéré que je devais ajouter using namespace std; à mon code!

Cependant, il n'y avait aucune mention d'espaces de noms dans le livre, alors j'ai pensé que le livre était obsolète. (Il utilise la directive #include <iostream.h> du préprocesseur!) Après quelques recherches supplémentaires sur le Web, j'ai trouvé de nombreuses informations sur les espaces de noms, namespace std, ainsi que des informations historiques sur <iostream.h> et <iostream>, et tout ce flux de nouvelles informations me confond. (Sans parler de tous les résultats inutiles de Google sur les MST médicales ...)

Donc, voici quelques questions que j'ai jusqu'à présent:

  1. Si j'inclus la bibliothèque iostream, pourquoi une namespace est-elle nécessaire pour trouver cout? Y a-t-il une autre cout quelque part qui pourrait causer un conflit de noms? Si quelqu'un pouvait fournir un diagramme pour cela, ce serait génial.

Et en prime, quelques antécédents historiques:

  1. Quel était exactement iostream.h avant qu'il ne soit remplacé par iostream?

  2. namespace a-t-il joué un rôle dans ce changement?

18
S.T.A.L.K.E.R.

Toutes les définitions de bibliothèque standard sont à l'intérieur de l'espace de noms std. C’est-à-dire qu’ils ne sont pas définis au niveau global, aussi, pour les utiliser, vous devez les qualifier de l’une des manières suivantes:

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

Par exemple, prenons ceci:

// declarations
int global_variable;

namespace n {
int variable2;
}

global_variable peut être accès tel quel:

int x;
x = global_variable;

Mais variable2 ne fait pas partie de l’espace global, mais fait partie du namespace n.

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

Donc, vous devez utiliser le nom complet:

int x;
x = n::variable2;

En tant que raccourci, vous pouvez écrire:

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

ou

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

En ce qui concerne les fichiers d’en-tête, iostream.h était utilisé par de nombreux compilateurs avant l’apparition d’une norme. Lorsque le comité a essayé de normaliser, il a décidé de rendre les en-têtes C++ sans extension afin de ne pas compromettre la compatibilité avec le code existant.

19
bolov

Cette ligne commençant par #, elle est appelée "directive de préprocesseur". Le préprocesseur Lit votre programme avant sa compilation et n'exécute que les lignes commençant par #. Le préprocesseur configure votre code source pour le compilateur.

La directive #include amène le préprocesseur à inclure le contenu d'un autre fichier dans le programme. Le fichier iostream contient du code qui permet à un programme C++ d'afficher les résultats à l'écran et de prendre des entrées à partir du clavier. Les fichiers iostream sont inclus dans le programme au moment où la directive #include apparaît. La iostream s'appelle un fichier d'en-tête et apparaît au début ou à la fin du programme.

using namespace std;

C++ utilise des espaces de noms pour organiser des noms ou des entités de programme. Il déclare que le programme évaluera les entités qui font partie de la namespace appelée "std". Chaque nom créé par le fichier iostream fait partie de cette namespace.

5
Jaythaceo

1.Si j'inclus la bibliothèque iostream, pourquoi une namespace est-elle nécessaire pour trouver cout? Y a-t-il une autre cout quelque part qui pourrait causer un conflit de noms?

Cela est nécessaire car la norme C++ requiert que cout soit situé dans l'espace de noms std. Il pourrait être une cout conflictuelle, mais pas dans la bibliothèque standard (par exemple, votre propre code ou une bibliothèque tierce.)

1.Qu'est-ce qu'exactement iostream.h avant qu'il ne soit remplacé par iostream?

Cela pourrait être n'importe quoi, car cela ne faisait pas partie de la norme, mais c'était le nom d'un en-tête de pré-normalisation qui constituait la base de iostream. Habituellement, tous les noms sont déclarés dans l'espace de noms global. Il est donc probable que l'exemple que vous regardez a été écrit avant la normalisation.

2. Est-ce que namespace a joué un rôle dans ce changement?

Cette question n'est pas claire. Le mot clé namespace peut être utilisé dans les implémentations et il est utilisé pour déclarer et définir des données, des fonctions, des types, etc. dans un espace de noms. Donc, il y a eu some dans ce changement.

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

En C++, vous pouvez logiquement regrouper les identifiants dans namespaces . cout flux est dans namespace std. Vous pouvez l'utiliser de 3 manières.

  1. Écrivez using namespace std en haut et utilisez cout comme vous l'avez fait.
  2. Écrivez using std::cout en haut et utilisez cout comme vous l'avez fait.
  3. Utilisez std::cout au lieu de cout
1
Mohit Jain