Tout d'abord, la terminologie:
-
aide-déclaration:
using std::vector;
-
à l'aide de la directive-:
using namespace std;
Je pense que l'utilisation de directives à l'aide sont très bien, tant qu'ils ne sont pas utilisés à la portée globale dans un fichier d'en-tête. Donc, avoir
using namespace std;
dans votre .fichier cpp n'est pas vraiment un problème, et si il s'avère, il est entièrement sous votre contrôle (et il peut même être portée à des blocs particuliers si vous le souhaitez). Je ne vois pas particlar raison d'encombrer le code avec un tas d' std::
qualificatifs - il devient juste un tas de bruit visuel. Toutefois, si vous n'êtes pas à l'aide de tout un tas de noms de l' std
d'espace de noms dans votre code, j'ai aussi ne voient aucun problème à laisser de la directive. C'est une tautologie - si la directive n'est pas nécessaire, alors il n'y a pas besoin de l'utiliser.
De même, si vous pouvez vous en tirer avec un peu d' aide de déclarations (au lieu de directives à l'aide) pour spécfiques types dans l' std
d'espace de noms, alors il n'y a aucune raison que vous ne devriez pas avoir seulement ceux spefcific noms introduit dans l'espace de noms courant. Par la même occasion, je pense qu'il serait de la folie et de comptabilité tracas d'avoir 25 ou 30 à l'aide de déclarations lorsqu'un seul à l'aide de la directive ferait l'affaire aussi bien.
Il est également bon de garder à l'esprit qu'il ya des moments où vous devez utiliser un aide-déclaration. Reportez-vous à Scott Meyers' "Article 25: Envisager un soutien pour un non-lancer swap" de l'Effective C++, Troisième Édition. Afin d'avoir un générique, basé sur un modèle de fonction utilisation de la "meilleure" méthode d'échange pour un type paramétré, vous avez besoin de faire usage d'une aide-déclaration et de l'argumentation à charge de recherche (aka ADL ou Koenig de recherche):
template< typename T >
void foo( T& x, T& y)
{
using std::swap; // makes std::swap available in this function
// do stuff...
swap( x, y); // will use a T-specific swap() if it exists,
// otherwise will use std::swap<T>()
// ...
}
Je pense que nous devrions nous pencher sur la commune de locutions pour différentes langues, qui font un usage important des espaces de noms. Par exemple, Java et C# utiliser des espaces de noms dans une large mesure (sans doute plus que le C++). La façon la plus courante de noms dans les espaces de noms sont utilisés dans ces langues est en les mettant à la portée actuelle en masse avec l'équivalent d'un à l'aide de la directive. Ce n'est pas une cause répandue de problèmes, et les rares fois où c'est un problème sont traités sur une "exception" en traitant avec les noms en question via complet des noms ou par aliasing tout comme peut être fait en C++.
Herb Sutter et Andrei Alexandrescu ont ceci à dire dans "Item 59: Ne pas écrire de l'usage de l'espace de noms dans un fichier d'en-tête ou devant un #include" de leur livre, C++ Normes de Codage: 101 Règles, des lignes Directrices et des Pratiques Exemplaires à:
En bref: Vous pouvez et devez utiliser l'espace de noms à l'aide des déclarations et des directives généreusement dans vos fichiers de mise en œuvre après l' #include
directives et de se sentir bien à ce sujet. En dépit des affirmations contraires, de l'espace de noms à l'aide de déclarations et directives ne sont pas mauvais et ils ne sont pas à l'encontre du but d'espaces de noms. Plutôt, ils sont ce qui rend les espaces de noms utilisable.
Stroupstrup est souvent cité comme disant, "Ne pas polluer l'espace de noms global", dans Le Langage de Programmation C++, Troisième Édition". Il n'est, en fait, dire que (C. 14[15]), mais se réfère au chapitre C. 10.1 où il dit:
Un aide-déclaration ajoute un nom à un
une portée locale. Un aide-directivene
pas; simplement, il rend noms
accessible dans le cadre dans lequel elles
ont été déclarés. Par exemple:
namespaceX {
int i , j , k ;
}
int k ;
void f1()
{
int i = 0 ;
using namespaceX ; // make names from X accessible
i++; // local i
j++; // X::j
k++; // error: X::k or global k ?
::k ++; // the global k
X::k ++; // X's k
}
void f2()
{
int i = 0 ;
using X::i ; // error: i declared twice in f2()
using X::j ;
using X::k ; // hides global k
i++;
j++; // X::j
k++; // X::k
}
Un déclarés localement nom (déclarée
soit par simple déclaration ou
par une aide-déclaration) se cache non
déclarations du même nom, et tout
illicite les surcharges du nom sont
détecté au moment de la déclaration.
Remarque l'erreur d'ambiguïté pour k++
dans
f1()
. Mondial les noms ne sont pas donnés
la préférence sur les noms d'espaces de noms
accessible dans la portée globale.
Cela permet une grande protection
contre les chocs, les collisions de noms, et –
important – s'assure qu'il y a
pas d'avantages
polluer l'espace de noms global.
Quand les bibliothèques déclarant beaucoup de noms
sont accessibles par l'intermédiaire de
directives à l'aide, il est important
l'avantage que les affrontements de la partie inutilisée des noms
ne sont pas considérées comme des erreurs.
...
J'espère voir une diminution radicale
l'utilisation de noms globaux dans les nouvelles
les programmes utilisant les espaces de noms par rapport à
traditionnelle programmes C et C++. L'
règles pour les espaces de noms ont été spécifiquement
conçu pour donner à aucun des avantages d'une
‘paresseux" utilisateur de noms globaux sur
quelqu'un qui prend soin de ne pas polluer
la portée globale.
Et comment a-t-on le même avantage que d'un "paresseux utilisateur de noms globaux'? En profitant de l'aide de la directive, qui en toute sécurité rend les noms dans un espace de noms disponibles à l'étendue actuelle.
Noter qu'il y a une distinction - noms dans l' std
de l'espace de noms à la disposition d'un champ avec la bonne utilisation de l'aide de la directive (en plaçant la directive après l' #includes
) ne pas polluer l'espace de noms global. C'est juste faire ces noms facilement, et avec une protection continue contre les affrontements.