Je ne comprends pas l'interêt de répéter sans cesse dans mon code 'std::' devant chaque instruction de la bibliothèque standard.
Pourquoi ne peut-on pas utiliser 'using namespace std' dans le main , tout simplement ?
Merci pour votre aide..
Je ne comprends pas l'interêt de répéter sans cesse dans mon code 'std::' devant chaque instruction de la bibliothèque standard.
Pourquoi ne peut-on pas utiliser 'using namespace std' dans le main , tout simplement ?
Merci pour votre aide..
Salut,
Un peu d'histoire:
Pour comprendre l'origine de cette directive qui pose souvent plus de problèmes qu'elle n'en résout, il faut savoir que les fonctionnalités de la bibliothèque standard n'ont été placées dans l'espace de noms std qu'avec la mise à jour de la norme effectuée en 1998.
Mais, à cette époque, le langage existait déjà depuis une bonne dizaine d'années, si bien qu'il y avait déjà une très grande quantité de projets qui l'utilisaient, ce qui se traduisait déjà à l'époque par une quantité de code phénoménale.
Il était, bien sur, hors de question d'obliger les développeurs à reprendre l'ensemble de leur code pour ajouter le préfixe std:: devant toutes les fonctionnalités de la bibliothèque standard qu'ils utilisaient, car cela aurait nécessité des heures de travail sur tous les projets.
Il fallait donc trouver un moyen de faire en sorte que ces projets continuent à compiler correctement malgré le passage éventuel à une version "plus récente" du compilateur, et qui ne nécessite qu'"un minimum" de modifications du code existant.
La directive using namespace n'a été créée que dans ce seul et unique but. Parce qu'il suffisait à l'époque de l'ajouter dans un fichier d'en-tête inclus partout (comme le fichier souvent nommé config.h) pour qu'elle puisse s'appliquer a priori dans n'importe quelle unité de compilation.
Seulement, voilà: cela fait maintenant plus de vingt ans que les fonctionnalités de la bibliothèques standard sont regroupées dans l'espace de noms std. On peut donc difficilement estimer que le code que l'on écrit "de nos jours" ait la moindre chance de devoir être compilé avec un compilateur datant d'avant 1998
Il n'y a donc aucun intérêt à utiliser cette directive de nos jours, d'autant plus qu'elle pose en définitive beaucoup plus de problèmes qu'elle n'en résout.
Comprendre les espaces de noms
Pour te permettre de comprendre l'intérêt, il faut déjà que tu comprenne celui des espaces de noms (namespaces en anglais).
Pour faire simple, un espace de noms est une "boite de rangement" dans laquelle tu pourras placer les fonctionnalités qui "vont bien ensembles". Que ce soit pour toi-même ou pour le compilateur, cela va permettre de faire la différence entre des fonctionnalités qui portent le même nom, mais qui ont des usage sans doute totalement différents, parce qu'elles sont issues de "boites de rangement" différentes.
Par exemple, la bibliothèque standard propose une classe (template) appelée std::vector, qui nous permet de gérer des tableaux d'éléments contigus en mémoire de maniière simple et sécurisante. Mais le terme vector en lui-même se traduit en français par "vecteur". Or, ce terme peut prendre des significations selon le domaine dans lequel on travaille:
- En mathématique, par exemple, un vecteur représente une segment de droite orienté, comme un couple de points ou une translation qui doit être effectuée, et on peut effectuer des opérations mathématiques sur deux ou plusieurs vercteurs (certaines d'entre elles ayant pour résultat la création de matrices).
- En médecine un "vecteur infectieux" ou un "vecteur de contagion" est un organisme (bactérie ou virus) susceptible de transmettre une infection ou une maladie aux gens.
Le problème, c'est que, que l'on veuille parler du tableau de la bibliothèque standard, d'un vecteur au sens mathématique ou d'un vecteur d'infection, nous utiliserons le même terme en anglais: vector.
Alors, imaginons que tu veuille créer un petit jeux avec différents éléments qui bougent à l'écran. Je te conseillerais sans doute de créer une classe (ou une structure) pour représenter la translation d'un objet et, comme j'ai l'habitude d'écrire mon code en anglais, je te conseillerais de l'appeler ... vector, et de placer cette structure dans un espace de noms dédié (que j'appellerais game pour l'occasion).
Puis, comme il y a plusieurs éléments qui doivent être déplacés à chaque frame, je te conseillerais de regrouper les vecteurs dans un tableau, de manière à pouvoir appliquer la translation adéquate à chaque objet. Ce qui nous pousserait à créer une instance de... vector (les tableaux de la bibliothèque standard) de... vector (les vecteurs que l'on a mis au point).
Au final, nous serions sans doute face à un code qui pourrait se réduire à quelque chose commeTant que tant que tu n'utiliseras pas la directive using namespace; tu n'auras pas de problème, car, le fait d'utiliser les noms pleinement qualifiés (std::vector et game::vector) évite tout risque de confusion pour le compilateur: il sait qu'il doit aller chercher dans l'espace de noms std pour trouver le tableau et dans l'espace de noms game pour trouver le vecteur mathématique.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 #include <vector> namespace game{ struct vector{ int x; int y }; } // namespace game int main(){ std::vector<Game::vector> translations; /* ... */ }
Oui, mais, qu'est ce que ca peut être emmerdant de devoir écrire à chaque fois std:: ou game:: !!! On va se simplifier la vie, et utiliser une directive using namespace std; pour pouvoir accéder directement aux tableaux par leur nom simplifié et, tant qu'à faire, on va utiliser une directive using namespace game; pour pouvoir accéder aux vecteurs de mathématiques; ce qui nous donnera un code proche de
C'est beaucoup plus simple, non
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <vector> using namespace std; namespace game{ /* rajoutons de l'ambiguité, car on peut traiter * n"importe quel type de valeur numérique */ template <typename T> struct vector{ /* par facilité */ using value_type = T; value_type x; value_type y }; } // namespace game using namespace game; int main(){ vector<vector<double>> translations; /* ... */ }
Sauf que, du coup, on crée une ambiguité: le compilateur se trouve face à deux classes qui portent le même nom, mais qui sont définie de manière totalement différente. Et il ne se gène pas pour le dire, car, si on essaye de compiler ce code avec gcc, nous obtenons un message ressemblant à
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 g++ main.cpp main.cpp:7:15: error: expected nested-name-specifier before 'value_type' using value_type; ^~~~~~~~~~ main.cpp:8:9: error: 'value_type' does not name a type value_type x; ^~~~~~~~~~ main.cpp:9:9: error: 'value_type' does not name a type value_type y; ^~~~~~~~~~ main.cpp: In function 'int main()': main.cpp:15:5: error: reference to 'vector' is ambiguous vector<vector<double>> translations; ^~~~~~ main.cpp:6:12: note: candidates are: 'template<class T> struct game::vector' struct vector{ ^~~~~~ In file included from D:/dev/mingw-8.1.0/x86_64/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/vector:64, from main.cpp:1: D:/dev/mingw-8.1.0/x86_64/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_vector.h:339:11: note: 'template<class _Tp, class _Alloc> class std::vector' class vector : protected _Vector_base<_Tp, _Alloc> ^~~~~~ main.cpp:15:12: error: reference to 'vector' is ambiguous vector<vector<double>> translations; ^~~~~~ main.cpp:6:12: note: candidates are: 'template<class T> struct game::vector' struct vector{ ^~~~~~ In file included from D:/dev/mingw-8.1.0/x86_64/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/vector:64, from main.cpp:1: D:/dev/mingw-8.1.0/x86_64/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_vector.h:339:11: note: 'template<class _Tp, class _Alloc> class std::vector' class vector : protected _Vector_base<_Tp, _Alloc> ^~~~~~ main.cpp:15:19: error: expected primary-expression before 'double' vector<vector<double>> translations;
Encore merci pour partager vos connaissances.
Vous avez très bien expliqué l'origine de la directive 'using namespace std', et je comprends parfaitement l'ambiguité de son utilisation aujourd'hui.
Malheuresement beaucoup de sites continuent à alimenter cet dilemme.
MERCI !!
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager