En lisant la norme Google, vous ne pouvez utiliser la using namespace foo;
directive nulle part. Cette directive apporte tout ce qui est déclaré dans l'espace de noms et est une cause courante de collisions et de comportements inattendus. D'autres en ont cité une très courante: vous avez votre propre méthode max ou min quelque part et elle entre en collision dans un fichier src où quelqu'un inclut un en-tête avec votre méthode et dit ensuiteusing namespace std;
Dans certains endroits, il est permis d'avoir une déclaration d'utilisation, qui est de la forme using ::foo::bar;
Les gens aiment mettre des directives d'utilisation dans leur code car cela économise beaucoup de frappe, mais cela comporte des risques. Si vous avez un fichier avec beaucoup d'instructions cout, je peux comprendre ne pas vouloir taper cent fois :: std :: cout, mais vous pouvez simplement dire en utilisant :: std :: cout. Je les traite comme des déclarations de variables: définissez-les là où elles sont nécessaires. Si une fonction dans un fichier de 10 a besoin d'écrire la sortie, ne déclarez pas le chemin cout en haut, mettez-la dans cette fonction qui fait la sortie réelle.
#include <ostream>
//using namespace std; // NO!
//using ::std::cout; // less bad than using namespace, but I prefer to scope it
int main(int argc, char** argv)
{
int rc = do_some_stuff(argc, argv);
using ::std::endl;
if (rc) { // print the success report
using ::std::cout;
cout << "The test run completed. The return code was " << rc << '.' << endl;
} else {
using ::std::cerr;
cerr << "Unable to complete the test run." << endl;
}
return 0 == rc;
}
C'est un peu extrême avec seulement quelques lignes faisant la sortie, mais vous avez l'idée.
Une autre chose que l'on peut faire est un alias ou un typedef pour minimiser la frappe. Je ne trouve pas que std :: any soit si mauvais, mais nous avons un énorme ensemble de sources avec plusieurs dizaines de modules et parfois nous devons écrire du code comme console_gui::command_window::append("text")
. Cela devient fastidieux après un certain temps et cause beaucoup de longues files d'attente. Je suis tout pour quelque chose comme
typedef console_gui::command_window cw;
cw::append("text");
tant que les alias sont effectués dans une portée locale et conservent suffisamment de contexte pour rendre le code lisible.
Michael Mathews
la source
std::endl
pour le vidage explicite surstdout
/stderr
est normalement assez superflue, ces flux sont liés àstdout
/ destderr
toute façon. Cela ralentit même un peu les choses.C'est parce que: 1) il va à l'encontre de l'objectif des espaces de noms, qui est de réduire la collision de noms; 2) il met à la disposition de l'espace de noms global tout l'espace de noms spécifié avec la directive using.
Par exemple, si vous incluez et définissez votre propre fonction max (), elle entrera en collision avec std :: max ().
http://en.cppreference.com/w/cpp/algorithm/max
La préférence est d'utiliser std :: member_you_wish_to_use car il indique explicitement quel espace de noms utiliser.
la source
std::max()
le préfixe d'espace de nom. Ou je me trompe?using
directives car dans ce cas, cela casserait votre fonction max () si vous en aviez défini une et inclus <algorithme>. C'est un cas simple mais vous ne savez jamais ce que vous pourriez casser. Vous auriez besoin de connaître la bibliothèque entière pour être sûr de ne pas la casser, mais vous ne pouvez pas savoir si votre code se briserait (c'est-à-dire collision de noms) à l'avenir.Citant le lien que vous fournissez:
Le style Google vous interdit d'utiliser des espaces de noms dans un contexte global, mais permet de le faire dans des espaces locaux.
Partout où l'utilisation de la déclaration n'affecte qu'une partie limitée et clairement visible du code, elle est parfaitement acceptable.
Lorsque vous polluez le contexte global, le code non lié est affecté (implicitement en utilisant votre en-tête). Rien ne se produit lorsque vous le faites dans un contexte local.
la source
Tu l'as fait. La recommandation ne s'applique qu'à la
using namespace
directive (qui est communément appeléeabusing namespace
, pas entièrement avec humour). Il est fortement préférable d'utiliser le nom complet d'une fonction ou d'un objet, tel questd::cout
.la source
Bien que la question ait déjà des réponses utiles, un détail semble trop court.
La plupart des programmeurs sont d'abord un peu confus avec le
using
mot - clé et les descriptions d'namespace
utilisation, même s'ils essaient de l'apprendre en recherchant la référence, car la déclaration et la directive se lisent quelque peu équivalentes, les deux sont des mots longs relativement abstraits commençant par d .Les identificateurs dans les espaces de noms sont accessibles en nommant explicitement l'espace de noms:
cela peut être beaucoup plus de touches à taper. Mais cela peut également diminuer la signification de votre code, si la plupart des identifiants sont préfixés de la même manière. Le
using
mot-clé permet d'éviter ces inconvénients de l'espace de noms. Étant donné qu'ilusing
fonctionne au niveau du compilateur (ce n'est pas une macro), son effet dure pour toute l'étendue dans laquelle il est utilisé. C'est pourquoi le style Google limite son utilisation à des étendues bien définies, c'est-à-dire des classes dans des fichiers d'en-tête ou des fonctions dans des fichiers cpp.... bien sûr, il y a une différence entre utiliser la déclaration
et en utilisant la directive
S'il est utilisé dans de vastes étendues, ce dernier conduit à beaucoup plus de confusion.
la source
Voici:
En l'écrivant de cette façon, nous évitons l'ADL sujet aux erreurs ainsi que l'utilisation de directives et de déclarations.
C'est censé être une réponse sarcastique. :-RÉ
Je suis avec Herb Sutter sur Google sur celui-ci. Des normes de codage C ++:
Vous pouvez être obsédé par les conflits d'espace de noms potentiels qui ne se manifesteront probablement jamais et ne seront probablement pas difficiles à résoudre dans un événement aussi rare sur le plan astronomique en évitant soigneusement les
using
directives et en spécifiant explicitement chaque chose que vous utilisez (jusqu'aux opérateurs) avec desusing
déclarations, ou allez-y et commencezusing namespace std
. Je recommande ce dernier du point de vue de la productivité.Le contraire si vous me le demandez, et je crois que Sutter ci-dessus est d'accord.
Maintenant, au cours de ma carrière, j'ai rencontré environ 3 conflits d'espace de noms au total en conséquence directe de
using
directives dans des bases de code couvrant des dizaines de millions de LOC. Cependant, dans les 3 cas, ils se trouvaient dans des fichiers source qui s'étalaient sur plus de 50 000 lignes de code hérité, initialement écrites en C puis bâtardées en C ++, effectuant une liste éclectique massive de fonctions disparates, y compris les en-têtes d'une douzaine de bibliothèques différentes, et ayant une liste épique de#includes
cela s'étalant sur une page. Malgré le désordre épique, ils n'ont pas été trop difficiles à réparer car ils ont causé des erreurs de build sur OSX (le seul OS où le code n'a pas pu être construit), pas des bugs d'exécution. N'organisez pas votre code de cette façon cauchemardesque et ça devrait aller.Cela dit, évitez les
using
directives et les déclarations dans les fichiers d'en-tête. C'est tout simplement retardé. Mais pour les fichiers source, et en particulier ceux qui n'ont pas une page entière remplie de#include
directives, je dirais ne pas transpirer si vous ne travaillez pas pour Google.la source