1
votes

Pourquoi n'avez-vous pas à #include , si vous incluez déjà l'utilisation de l'espace de nom std?

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.


3 commentaires

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 .


6 Réponses :


3
votes

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 .


6 commentaires

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



0
votes

#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 foo 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 .


1 commentaires

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?



-1
votes

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.


3 commentaires

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.



1
votes

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 library

Cependant, 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 noms std .

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


0 commentaires

0
votes

Premièrement, std: vector - // bla, un vecteur est créé. 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....


0 commentaires

1
votes

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).


1 commentaires

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.