J'ai appris l'informatique orientée objet et en particulier les itérateurs et les bibliothèques de modèles standards etc.
Je ne comprends pas très bien pourquoi si vous écrivez
#include <iostream> #include <algorithm> #include <iterator> #include <vector> using namespace std; int main() { vector<int>::iterator pos; vector<int>coll; }
Cependant, dans certains cas, vous devez écrire
std::vector<int>::iterator pos; std::vector<int>coll;
Pourquoi? La bibliothèque standard où nous écrivons habituellement "using namespace std" - inclut-elle déjà la bibliothèque vectorielle?
Quand je supprime le fichier de définition #include, l'ordinateur ne peut pas reconnaître mes variables vectorielles.
Cependant, j'ai vu dans certains cas que de nombreuses personnes ont utilisé la fonction vectorielle sans la déclarer en utilisant std :: vector ???
#include <vector> //to include vector library
c'est le code que d'autres personnes utilisent et il semble fonctionner?
std:vector<int> - //blah, a vector is created.
// cela fonctionne pour moi, mais je veux comprendre pourquoi celui-ci fonctionne et l'autre ne fonctionne pas 't.
6 Réponses :
La directive using namespace std;
dit simplement "Pour tout ce qui se trouve dans l'espace de noms std
que je connais , vous pouvez laisser le < code> std :: préfixe ". Mais sans #include
(directement ou indirectement via un autre #include
), le compilateur n'a aucune idée de l'existence de std :: vector
en premier lieu.
Les en-têtes vous donnent les déclarations (et dans certains cas, les définitions) de diverses classes et API; la déclaration using namespace
supprime simplement la nécessité de qualifier explicitement vos références avec un préfixe d'espace de noms.
La raison pour laquelle vous êtes toujours tenu d'effectuer les #include
s concerne la déconfliction des déclarations (vous ne voulez pas simplement inclure tous les fichiers d'inclusion possibles, car certains d'entre eux peuvent avoir des définitions contradictoires de certains noms), et les performances de compilation ( #include
dans le monde signifie plusieurs kilo-octets, voire des mégaoctets, de code supplémentaire à compiler, dont la grande majorité vous n'utiliserez pas réellement; le limiter à les en-têtes dont vous avez réellement besoin signifient moins d'E / S disque, moins de mémoire et moins de temps CPU pour effectuer la compilation.
Pour référence future, "où nous écrasons habituellement 'using namespace std;'" indique que vous avez appris de mauvaises habitudes. using namespace std;
est mal vu dans le code de production .
Pourquoi voulez-vous dire "pour tout ce que je sais"?
en fait, je comprends ce que vous dites maintenant! Merci beaucoup!!
@HasanHussaini: "I" dans ce cas fait référence au compilateur; la directive dit que "tout ce que le compilateur sait à propos de std
n'a pas besoin d'être qualifié par std
par le programmeur". Je parlais de manière quelque peu informelle en utilisant «je» et «vous», désolé si cela confondait.
Cela ne répond qu'à la moitié de la question. Pourquoi les autres exemples de code n'ont-ils pas besoin de l'inclusion?
@MooingDuck: J'ai mentionné qu'au passage quand j'ai dit "sans le #include
(directement ou indirectement via un autre #include
), le compilateur n'a aucune idée < code> std :: vector existe en premier lieu. " La réponse à la raison pour laquelle certains exemples de code fonctionnent sans l'inclusion est qu'ils incluaient un autre en-tête qui à son tour inclut
. Si ce n'est pas le cas, alors il n'y a pas de définition de std :: vector
, et le code échoue avec des types non définis. Il doit être inclus, mais cela ne signifie pas que vous l'avez inclus directement (cela dit, vous devriez, pour éviter que les changements d'en-tête n'interrompent la compilation).
@ShadowRanger: C'est une excellente explication. Mettez-le dans la réponse s'il vous plaît: D
#include
remplace simplement la directive #include
par le contenu du fichier "some_file".
Dans le cas de #include
, le fichier "vector" contient la définition du modèle de classe vecteur
dans le std
espace de noms. Pour déclarer une instance d'une classe, la définition de cette classe doit être visible par le compilateur, donc pour déclarer std :: vector
vous devez #include
, soit directement ou indirectement en #include
un autre fichier qui #include
est.
Alors pourquoi certains exemples de code doivent #include
et d'autres non? Eh bien, ils le font tous. Certains peuvent ne pas #include
explicitement, mais ils doivent #include
un autre fichier qui contient #include
.
Bien sûr, dans de nombreux exemples d'extraits de code, les gens omettent simplement les #include
par souci de concision. Le code ne se compilera pas sans les bons #include
, mais ils allongent le code et peuvent distraire du point que l'auteur essaie de faire.
L'instruction using namespace std;
indique simplement au compilateur qu'il doit rechercher dans l'espace de noms std
tous les noms non qualifiés qu'il ne peut pas trouver dans l'espace de noms actuel. Cela signifie que le compilateur peut trouver la classe vector
à la fois par les noms vector
et std :: vector
.
Cela ne répond clairement qu'à la moitié de la question et ne fait qu'indiquer la réponse à l'autre moitié. Pourquoi les autres exemples de code n'ont-ils pas besoin de l'inclusion?
Les vecteurs font partie du C ++ STL, oui, mais vous devez inclure le fichier d'en-tête
pour pouvoir l'utiliser. C'est la même raison pour laquelle vous devez #include
si vous souhaitez utiliser des chaînes STL. Après avoir inclus ces en-têtes, vous devez utiliser l'identificateur d'espace de noms std ::
avant de déclarer un vecteur ou une chaîne, afin que le compilateur sache que ce que vous déclarez fait partie du C ++ STL et n'est pas construit -in en C ou C ++ "de base".
En gros, ce que fait using namespace std
, c'est vous donner la possibilité de supprimer le qualificatif std ::
avant votre string
ou vecteur
ou autre. Ce n'est pas recommandé, voici un article expliquant brièvement pourquoi vous ne devriez pas l'utiliser. Au lieu de cela, si vous souhaitez nettoyer votre code et que vous ne souhaitez pas taper std ::
chaque fois que vous souhaitez imprimer sur la console, envisagez d'importer des identifiants uniques, par exemple en utilisant l'espace de noms std :: cout
à la place.
J'espère que cela vous aidera.
Cela ne répond qu'à la moitié de la question. Pourquoi les autres exemples de code n'ont-ils pas besoin de l'inclusion?
Comme cela a été mentionné dans d'autres réponses, le code d'autres personnes pourrait inclure des en-têtes qui ont des vecteurs, mais il n'y a aucune garantie
Par Sergey Zubkov de quora. com / In-C-what-is-stl-and-std-How-are-they-different : «STL» («standard template library») était le nom d'une bibliothèque C ++ de Hewlett-Packard dans le début des années 1990. Il a été extrêmement influent dans le développement de la bibliothèque standard C ++ en 1998, et ce fut sa perte: HP ne voyait pas la nécessité de maintenir STL, il a passé plus d'une décennie abandonnée sur le site Web de SGI, et est maintenant parti. ".... Votre le compilateur conforme (tel que g ++ 9.2.1 sur Lubuntu 19.10) est livré avec la "bibliothèque standard C ++" et vous devriez l'utiliser (pas la STL abandonnée), c'est-à-dire que 'vector' est inclus.
Pourquoi n'avez-vous pas à #include, si vous incluez déjà en utilisant l'espace de nom std?
Vous devez inclure
uniquement si vous utilisez les déclarations de cet en-tête. Sinon, vous n'avez pas besoin de l'inclure. Vous n'avez jamais besoin
d'utiliser namespace std;
.ne semble pas tout à fait comprendre pourquoi si vous écrivez
#include <vector> //to include vector libraryCependant, dans certains cas, vous devez écrire
std:vector<int> - //blah, a vector is created.Vous toujours devez inclure
si vous créez des objets
std:vector
. p >La bibliothèque standard où nous écrivons habituellement "using namespace std" - inclut-elle déjà la bibliothèque vectorielle?
Non, la bibliothèque standard n'utilise pas
using namespace std;
. Si c'était le cas, cela invaliderait tout l'intérêt d'utiliser l'espace de nomsstd
.Lorsque je supprime le fichier de définition #include, l'ordinateur ne peut pas reconnaître mes variables vectorielles.
C'est parce que vous ne pouvez pas déclarer une variable d'un type qui n'a pas été défini. La définition de
std :: vector
est dans
Premièrement, std: vector
ne se compilera pas car vous avez utilisé un seul deux-points :
ce qui signifie que std voici une déclaration label
. et un nom d'étiquette ne peut pas être vector
. Donc je suppose que vous vouliez dire: std::vector
.
Deuxièmement, comme vous le savez peut-être, vector
, iostream
, .. . sont des types de bibliothèques définis respectivement dans les en-têtes
,
... Pour utiliser ces types, vous devez d'abord inclure ces en-têtes directement ou indirectement. p >
namespace std
en C ++ est un regroupement d'identificateurs qui est utilisé pour réduire la possibilité de dénomination de collisions. Dans le C ++ moderne, toutes les fonctionnalités de la bibliothèque standard C ++ sont désormais définies dans l'espace de noms std (abréviation de standard).
Regardez par exemple std :: cout
; cet identifiant est déclaré dans l'espace de noms std
dont le type est ostream
. Donc, vous devez d'abord inclure iostream
afin que la compilation puisse voir quel est l'objet ostream
et ensuite dire au compilateur où cet objet est déclaré? dans l'espace de noms std
. Donc, inclure uniquement iostream
n'est pas suffisant, donc vous ajoutez tout le contenu de l'espace de noms std
dans lequel cout
est déclaré, ou dites simplement au compilateur explicitement où cout
est déclaré en le qualifiant complètement:
#include <iostream> // contains output/input library types definitions using std::cout; // ok add only cout definition to the program not the whole content of std. using namespace std; // contains cout, cin, vector....
Pourquoi n'incluez-vous pas
si vous incluez déjà l'utilisation namespace std Jetez un œil à cette URL: https://en.cppreference.com/w/ cpp / header
Il y a plus de 100 fichiers d'en-tête disponibles pour votre utilisation.
À mon humble avis, la confusion que vous rencontrez est que ces mêmes 100+ en-têtes sont ÉGALEMENT disponibles pour les auteurs des en-têtes, et ils ont également accès à des en-têtes qui ne sont généralement pas publiés dans le standard. Le résultat est que, par exemple, lorsque vous ou moi incluons
, une partie indirecte de cette inclusion pourrait également «pull-in» . Je vous recommande de ne pas mettre "using namespace std" dans votre code. Son utilisation n'a pas causé intentionnellement l'inclusion «cachée / indirecte» de
, et peut-être pas lors de la prochaine implémentation. Je suis sur g ++ v7.3. Je vais bientôt passer à la version actuelle de g ++ (je pense 9.x?) Vous ne pouvez pas compter sur l'inclusion de
à moins que vous ne l'incluiez explicitement. cela fonctionne pour moi, mais je veux comprendre pourquoi celui-ci fonctionne et le l'autre non.
Juste de la chance ... Je pense que mauvais, si vous commencez plusieurs mauvaises habitudes à cause de cela.
Si votre compilateur prend en charge -std = c ++ 17 ou mieux, il a une nouvelle fonctionnalité que j'aime. La nouvelle fonctionnalité me permet, immédiatement après l'en-tête include, de spécifier la fonction de cette bibliothèque dont j'ai spécifiquement besoin. Cela ressemble à ceci:
#ifndef DTB_ENG_FORMAT_HH #include "../../bag/src/dtb_eng_format.hh" using DTB::EngFormat_t; #endif #ifndef DTB_PPLSEM_HH #include "../../bag/src/dtb_pplsem.hh" using DTB::PPLSem_t; #endif #ifndef DTB_ENG_FORMAT_HH #include "../../bag/src/dtb_eng_format.hh" #endif #ifndef DTB_ASSERT_HH #include "../../bag/src/dtb_assert.hh" #endif
Vos propres bibliothèques peuvent être gérées de la même manière:
#include <iostream> using std::cout, std::cerr, std::endl, std::flush, std::hex, std::dec, std::cin; #include <iomanip> using std::setw, std::setfill; #include <string> using std::string, std::to_string; #include <thread> using std::thread, std::this_thread::sleep_for; #include <vector> using std::vector;J'essaye de garder tracez un petit ensemble de ces derniers et rassemblez-les dans un fichier. J'utilise les plus grandes listes lorsque je commence un nouvel effort, et supprime trivialement les fonctions «inutilisées» (lorsque je veux publier mes efforts).
Merci pour l'information. Dans sa propre configuration VS, il y a
qui extrait
, où le risque de ne pas inclure
est au prix de en espérant qu'il ne sera pas extrait de
pendant la durée de vie du code.
utilisant l'espace de noms std; // ceci est une directive using indiquant au compilateur de vérifier l'espace de noms std lors de la résolution des identificateurs sans préfixe
- learncpp.com/cpp-tutorial/...Dans tous les cas, vous devez utiliser
#include
, pas seulement parce qu'il ne compile pas. Un autre en-tête peut l'inclure, mais il n'y a aucune garantie.std:vector
un point-virgule est uneétiquette
.