D'autres m'ont dit que l'écriture using namespace std;
dans le code est incorrecte et que je devrais utiliser std::cout
et std::cin
directement à la place.
Pourquoi est-ce using namespace std;
considéré comme une mauvaise pratique? Est-ce inefficace ou risque-t-il de déclarer des variables ambiguës (variables qui partagent le même nom qu'une fonction dans l' std
espace de noms)? Cela a-t-il un impact sur les performances?
c++
namespaces
std
using-directives
c++-faq
akbiggs
la source
la source
std::literals::chrono_literals
,Poco::Data:Keywords
,Poco::Units
et d'autres choses qui traitera des littéraux ou des astuces de lisibilité. Chaque fois qu'il se trouve dans des fichiers d'en-tête ou d'implémentation. Cela pourrait être OK dans une portée de fonction, je suppose, mais à part les littéraux et les trucs, ce n'est pas utile.Réponses:
Ce n'est pas du tout lié aux performances. Mais considérez ceci: vous utilisez deux bibliothèques appelées Foo et Bar:
Tout fonctionne bien, et vous pouvez appeler
Blah()
de Foo etQuux()
de Bar sans problème. Mais un jour, vous passez à une nouvelle version de Foo 2.0, qui propose désormais une fonction appeléeQuux()
. Vous avez maintenant un conflit: Foo 2.0 et Bar importentQuux()
dans votre espace de noms global. Cela va prendre un certain effort à résoudre, surtout si les paramètres de fonction correspondent.Si vous aviez utilisé
foo::Blah()
etbar::Quux()
, alors l'introduction defoo::Quux()
aurait été un non-événement.la source
#define
est qu'il ne se limite pas aux espaces de noms, mais piétine toute la base de code. Un alias d'espace de noms est ce que vous voulez.Je suis d'accord avec tout ce que Greg a écrit , mais j'aimerais ajouter: cela peut même empirer ce que Greg a dit!
La bibliothèque Foo 2.0 pourrait introduire une fonction,
Quux()
qui correspond sans aucun doute mieux à certains de vos appelsQuux()
que lebar::Quux()
code appelé depuis des années. Ensuite, votre code compile toujours , mais il appelle silencieusement la mauvaise fonction et fait quoi que ce soit. C'est aussi mauvais que les choses peuvent arriver.Gardez à l' esprit que l'
std
espace de noms a des tonnes d'identificateurs, dont beaucoup sont très plus communs (penserlist
,sort
,string
,iterator
, etc.) qui sont très susceptibles d'apparaître dans tout autre code, aussi.Si vous considérez cela comme improbable: Il y avait une question posée ici sur Stack Overflow où à peu près exactement cela s'est produit (mauvaise fonction appelée en raison du
std::
préfixe omis ) environ six mois après avoir donné cette réponse. Voici un autre exemple plus récent d'une telle question. C'est donc un vrai problème.Voici un autre point de données: il y a de nombreuses années, je trouvais également ennuyeux de devoir tout préfixer de la bibliothèque standard avec
std::
. Ensuite, j'ai travaillé dans un projet où il a été décidé au début que lesusing
directives et les déclarations étaient interdites, sauf pour les étendues de fonction. Devine quoi? La plupart d'entre nous ont mis très peu de semaines à s'habituer à écrire le préfixe, et après quelques semaines de plus, la plupart d'entre nous ont même convenu que cela rendait le code plus lisible . Il y a une raison à cela: que vous aimiez une prose plus ou moins longue est subjectif, mais les préfixes ajoutent objectivement de la clarté au code. Non seulement le compilateur, mais vous aussi, trouvez plus facilement à quel identifiant il est fait référence.En une décennie, ce projet s'est développé pour compter plusieurs millions de lignes de code. Étant donné que ces discussions reviennent encore et encore, j'ai été curieux de savoir à quelle fréquence la fonction (autorisée)
using
était réellement utilisée dans le projet. J'ai recherché les sources et trouvé seulement une ou deux douzaines d'endroits où il était utilisé. Pour moi, cela indique qu'une fois essayé, les développeurs ne trouvent passtd::
assez pénible d'utiliser des directives, même une fois tous les 100 kLoC, même là où il a été autorisé à les utiliser.Conclusion: préfixer explicitement tout ne fait pas de mal, demande très peu de temps pour s'y habituer et présente des avantages objectifs. En particulier, cela rend le code plus facile à interpréter par le compilateur et par les lecteurs humains - et cela devrait probablement être l'objectif principal lors de l'écriture de code.
la source
string
classe standard , et apparemment chaque bibliothèque avait la sienne. Dites-vous quoi: Nous continuerons d'écrire notre code avecstd::
, et vous pourrez exécuter notre code tout au long degrep -v std:: | vim
votre navigation. Ou vous pouvez apprendre à votre éditeurstd::
un mot-clé qui doit être coloré de la même manière que la couleur d'arrière-plan. Tout ce qui fonctionne.std::
soit nocif du tout. Il contient des informations très importantes (à savoir "tout ce qui vient après fait partie de la bibliothèque standard", et c'est toujours un préfixe assez court et compact. La plupart du temps, ce n'est pas un problème du tout. Parfois, vous avez quelques lignes de code où vous devez souvent faire référence à des symboles spécifiques dans l'std
espace de noms, puis uneusing
déclaration dans cette portée particulière résout bien le problème. Mais dans le cas général, ce n'est pas du bruit, il transmet des informations précieuses en plus de lever les ambiguïtés.std::
, je sais que ça va venirstd::
sans avoir à y penser. Si je voisstring
oulist
oumap
par eux-mêmes, je me demande un peu.vector
,transform
oudistance
. Et ce ne sont que des exemples des nombreux noms très courants utilisés dans la bibliothèque standard. Il est plutôt contre-productif de suggérer de ne pas les utiliser par peur ou par une opinion biaisée de la fonctionnalité d'espace de noms qui fait partie intégrante de C ++.Le problème avec la mise
using namespace
dans les fichiers d'en-tête de vos classes est qu'il oblige quiconque veut utiliser vos classes (en incluant vos fichiers d'en-tête) à «utiliser» (c'est-à-dire tout voir) dans ces autres espaces de noms.Cependant, vous pouvez vous sentir libre de mettre une instruction using dans vos fichiers (privés) * .cpp.
Attention, certaines personnes ne sont pas d'accord avec mon énoncé "n'hésitez pas" comme ceci - parce que même si une
using
déclaration dans un fichier cpp est meilleure que dans un en-tête (car elle n'affecte pas les personnes qui incluent votre fichier d'en-tête), ils pensent que ce n'est toujours pas le cas bon (car en fonction du code, cela pourrait rendre l'implémentation de la classe plus difficile à maintenir). Cette entrée C ++ Super-FAQ dit,La FAQ propose deux alternatives:
Une déclaration d'utilisation:
Il suffit de taper std ::
la source
J'ai récemment rencontré une plainte concernant Visual Studio 2010 . Il s'est avéré que presque tous les fichiers source avaient ces deux lignes:
De nombreuses fonctionnalités Boost sont intégrées dans la norme C ++ 0x, et Visual Studio 2010 possède de nombreuses fonctionnalités C ++ 0x, donc soudainement ces programmes ne se compilaient pas.
Par conséquent, en évitant
using namespace X;
est une forme de pérennisation, un moyen de s'assurer qu'une modification des bibliothèques et / ou des fichiers d'en-tête utilisés ne va pas casser un programme.la source
using
dehors d'une définition de fonction et j'utilise rarementusing namespace
du tout.Version courte: n'utilisez pas de
using
déclarations ou directives globales dans les fichiers d'en-tête. N'hésitez pas à les utiliser dans les fichiers d'implémentation. Voici ce que Herb Sutter et Andrei Alexandrescu ont à dire à propos de ce problème dans les normes de codage C ++ (les caractères gras sont les miens):la source
using
ne devrait jamais apparaître dans un en-tête, je ne suis pas aussi convaincu de la licence gratuite à placerusing namespace xyz;
n'importe où dans votre code, surtout sixyz
c'est le casstd
. J'utilise leusing std::vector;
formulaire, car cela ne tire qu'un seul élément de l'espace de noms dans une portée pseudo-globale, ce qui entraîne donc beaucoup moins de risques de collision.using namespace
c'est mal commegoto
c'est mal. Les deux ont des utilisations valides, mais 999 fois sur 1000, ils seront mal utilisés. Donc, oui, avecusing namespace
la source, vous ne polluerez pas l'espace de noms des autres inclus, bien. Mais cela ne vous protègera toujours pas contre le "plaisir" qui découle deusing namespace Foo
+using namespace Bar
avec votre appel (Foo implicite: :)baz(xyz)
et soudainement la rupture du code (sans changements associés) simplement parce queBar::baz()
ajouté quelque part, ce qui se trouve être un meilleur match (et est donc désormais appelé à la place)Il ne faut pas utiliser la
using
directive à l'échelle mondiale, en particulier dans les en-têtes. Cependant, il existe des situations où cela est approprié même dans un fichier d'en-tête:C'est mieux qu'une qualification explicite (
std::sin
,std::cos
...), car elle est plus courte et a la capacité de travailler avec des types à virgule flottante définis par l'utilisateur (via la recherche dépendante de l'argument (ADL)).la source
using std::cos;
,using std::sin
Etc. La question est bien que tout bien conçuuserlib
va avoir leursin
etcos
dans leur propre espace de noms aussi bien, donc cela ne vraiment pas vous aider. (À moins qu'il y ait unusing namespace userlib
avant ce modèle et que ce soit aussi mauvais queusing namespace std
- et la portée là-bas n'est pas limitée.) En outre, la seule fonction comme celle-ci que je vois jamais arriver estswap
, et dans de tels cas, je recommanderais simplement de créer un modèle spécialisationstd::swap
et éviter tout le problème.template<typename T> void swap(MyContainer<T>&, MyContainer<T>&)
(Il n'y a pas de spécialisation partielle de modèle de fonction (FTPS), donc parfois vous devez recourir à la surcharge à la place.x
a un ou plusieurs "espaces de noms associés" (par exemple, s'il a été défini dansnamespace userlib
), alors tout appel de fonction qui ressemblecos(x)
apparaîtra également dans ces espaces de noms - sans qu'aucunusing namespace userlib;
préalable ne soit nécessaire. Zan Lynx a raison (et la recherche de nom C ++ est byzantine ...)Ne l'utilisez pas globalement
Il est considéré comme «mauvais» uniquement lorsqu'il est utilisé à l'échelle mondiale . Parce que:
using namespace xyz
.using namespace std
vous, vous pourriez ne pas être au courant de toutes les choses que vous saisissez - et lorsque vous en ajoutez une autre#include
ou passez à une nouvelle révision C ++, vous risquez d'obtenir des conflits de noms dont vous n'étiez pas au courant.Vous pouvez l'utiliser localement
Allez-y et utilisez-le localement (presque) librement. Cela, bien sûr, vous empêche de répéter
std::
- et la répétition est également mauvaise.Un idiome pour l'utiliser localement
En C ++ 03, il y avait un idiome - code passe-partout - pour implémenter une
swap
fonction pour vos classes. Il a été suggéré que vous utilisiez réellement un localusing namespace std
- ou au moinsusing std::swap
:Cela fait la magie suivante:
std::swap
forvalue_
, c'est-à-direvoid std::swap(int, int)
.void swap(Child&, Child&)
implémentée, le compilateur la choisira.void std::swap(Child&,Child&)
et essaiera de les échanger au mieux.Avec C ++ 11, il n'y a plus de raison d'utiliser ce modèle. L'implémentation de a
std::swap
été modifiée pour trouver une surcharge potentielle et la choisir.la source
swap
en premier lieu n'est plus très important en C ++ 11, car lestd::swap
lui-même est plus flexible (utilise la sémantique de déplacement). Maisstd::swap
choisir automatiquement votre propre swap personnalisé, c'est absolument nouveau pour moi (et je n'y crois pas vraiment).using std::swap;
plutôt queusing namespace std;
. L'idiome plus spécifique a moins d'effets secondaires et rend donc le code plus maintenable.swap
, et divers autres endroits de la norme ont été modifiés pour dire qu'ils appellentswap
comme ça (NB comme indiqué ci-dessus,using std::swap
c'est la bonne façon, nonusing namespace std
). Maisstd::swap
lui-même n'a absolument pas changé pour en trouver un autreswap
et l'utiliser. Sistd::swap
est appelé, ilstd::swap
s'habitue.using std::swap
localement pour réduire l'espace de noms local tout en créant du code auto-documenté. Vous êtes rarement intéressé par tout l'espace de noms std, alors choisissez simplement les parties qui vous intéressent.Si vous importez les fichiers d' en- tête de droite , vous avez soudainement des noms comme
hex
,left
,plus
oucount
dans votre portée globale. Cela peut être surprenant si vous ne savez pas quistd::
contient ces noms. Si vous essayez également d'utiliser ces noms localement, cela peut entraîner une certaine confusion.Si tous les éléments standard se trouvent dans son propre espace de noms, vous n'avez pas à vous soucier des collisions de noms avec votre code ou d'autres bibliothèques.
la source
distance
. Je préfère toujours les noms non qualifiés dans la mesure du possible, car cela augmente la lisibilité pour moi. De plus, je pense que le fait que nous ne qualifions généralement pas les choses dans le discours oral et que nous sommes prêts à passer du temps à résoudre les ambiguïtés possibles, signifie qu'il a une valeur pour être en mesure de comprendre ce dont on parle sans qualifications et appliqué à la source code qui signifie qu'il est structuré de telle manière qu'il est clair de quoi il s'agit, même sans qualifications.<iomanip>
. Encore un bon point.Une autre raison est la surprise.
Si je vois
cout << blah
, au lieu destd::cout << blah
je pense: qu'est-ce que c'estcout
? Est-ce normalcout
? Est-ce quelque chose de spécial?la source
cout
est un mauvais exemple car tout le monde le reconnaît. Mais imaginezfuture
dans une application financière. Est-ce un contrat pour acheter ou vendre quelque chose à une date spécifiée? Non ça ne l'est pas. Si le code disait questd::future
vous ne seriez pas si facilement confondu.Les programmeurs expérimentés utilisent tout ce qui résout leurs problèmes et évitent tout ce qui crée de nouveaux problèmes, et ils évitent les directives d'utilisation au niveau du fichier d'en-tête pour cette raison exacte.
Les programmeurs expérimentés tentent également d'éviter la qualification complète des noms dans leurs fichiers source. Une raison mineure à cela est qu'il n'est pas élégant d'écrire plus de code lorsque moins de code est suffisant, sauf s'il existe de bonnes raisons . Une raison principale à cela est la désactivation de la recherche dépendante des arguments (ADL).
Quelles sont ces bonnes raisons ? Parfois, les programmeurs veulent explicitement désactiver ADL, d'autres fois ils veulent lever l'ambiguïté.
Donc, ce qui suit est OK:
la source
Je suis d'accord qu'il ne devrait pas être utilisé globalement, mais ce n'est pas si mal d'utiliser localement, comme dans a
namespace
. Voici un exemple de "The C ++ Programming Language" :Dans cet exemple, nous avons résolu les conflits de noms potentiels et les ambiguïtés résultant de leur composition.
Les noms qui y sont explicitement déclarés (y compris les noms déclarés par des déclarations using comme
His_lib::String
) ont priorité sur les noms rendus accessibles dans une autre portée par une directive using (using namespace Her_lib
).la source
Je considère également que c'est une mauvaise pratique. Pourquoi? Un jour, j'ai pensé que la fonction d'un espace de noms était de diviser des choses, donc je ne devrais pas le gâcher en jetant tout dans un seul sac global.
Cependant, si j'utilise souvent 'cout' et 'cin', j'écris:
using std::cout; using std::cin;
dans le fichier .cpp (jamais dans le fichier d'en-tête car il se propage avec#include
). Je pense que personne sain d'esprit ne nommera jamais un fluxcout
oucin
. ;)la source
C'est agréable de voir le code et de savoir ce qu'il fait. Si je vois,
std::cout
je sais que c'est lecout
flux de lastd
bibliothèque. Si je vois,cout
je ne sais pas. Ce pourrait être lecout
flux de lastd
bibliothèque. Ou il pourrait y avoirint cout = 0;
dix lignes plus haut dans la même fonction. Ou unestatic
variable nomméecout
dans ce fichier. Ça pourrait être n'importe quoi.Maintenant, prenez une base de code d'un million de lignes, ce qui n'est pas particulièrement gros, et vous recherchez un bogue, ce qui signifie que vous savez qu'il y a une ligne dans ce million de lignes qui ne fait pas ce qu'elle est censée faire.
cout << 1;
pourrait lire unstatic int
nomcout
, le déplacer d'un bit vers la gauche et jeter le résultat. Vous cherchez un bug, je devrais vérifier cela. Pouvez-vous voir comment je préfère vraiment voirstd::cout
?C'est une de ces choses qui semble vraiment une bonne idée si vous êtes un enseignant et que vous n'avez jamais eu à écrire et à maintenir un code pour vivre. J'adore voir du code où (1) je sais ce qu'il fait; et, (2) je suis convaincu que la personne qui l'écrit savait ce qu'il fait.
la source
Il s'agit de gérer la complexité. L'utilisation de l'espace de noms entraînera des choses que vous ne voulez pas, et donc rendra peut-être plus difficile le débogage (je dis peut-être). Utiliser std :: partout est plus difficile à lire (plus de texte et tout ça).
Chevaux pour les cours - gérez votre complexité comme vous le pouvez et sentez-vous le mieux possible.
la source
Considérer
Notez que ceci est un exemple simple. Si vous avez des fichiers avec 20 inclusions et autres importations, vous aurez une tonne de dépendances à traverser pour comprendre le problème. Le pire, c'est que vous pouvez obtenir des erreurs non liées dans d'autres modules en fonction des définitions en conflit.
Ce n'est pas horrible, mais vous vous éviterez des maux de tête en ne l'utilisant pas dans les fichiers d'en-tête ou l'espace de noms global. C'est probablement bien de le faire dans des portées très limitées, mais je n'ai jamais eu de problème à taper les cinq caractères supplémentaires pour clarifier d'où viennent mes fonctions.
la source
Vous devez être capable de lire du code écrit par des personnes qui ont des opinions de style et de meilleures pratiques différentes de vous.
Si vous utilisez uniquement
cout
, personne ne se trompe. Mais lorsque vous avez beaucoup d'espaces de noms qui volent et que vous voyez cette classe et que vous n'êtes pas exactement sûr de ce qu'elle fait, avoir l'espace de noms explicite agit en quelque sorte comme un commentaire. Vous pouvez voir à première vue, "oh, c'est une opération de système de fichiers" ou "qui fait des trucs de réseau".la source
L'utilisation de nombreux espaces de noms en même temps est évidemment une recette pour un désastre, mais en utilisant l'espace de noms JUST
std
et uniquement l'espace de nomsstd
n'est pas si grave à mon avis car la redéfinition ne peut se produire que par votre propre code ...Il suffit donc de les considérer comme des fonctions réservées comme "int" ou "classe" et c'est tout.
Les gens devraient cesser d'être si anaux à ce sujet. Votre professeur avait raison depuis le début. Utilisez simplement UN espace de noms; c'est tout l'intérêt d'utiliser les espaces de noms en premier lieu. Vous n'êtes pas censé en utiliser plusieurs en même temps. A moins que ce ne soit le vôtre. Encore une fois, la redéfinition ne se produira pas.
la source
min
,end
etless
apparaissent dans l'std::
espace de noms. Mais de plus, maintenant qu'ilstd::
contient des milliers de symboles, il est utile pour le lecteur de savoir d'où vient un nouveau symbole qu'il ne connaît peut-être pas.Je suis d'accord avec les autres ici, mais je voudrais répondre aux préoccupations concernant la lisibilité - vous pouvez éviter tout cela en utilisant simplement des typedefs en haut de votre fichier, fonction ou déclaration de classe.
Je l'utilise généralement dans ma déclaration de classe car les méthodes d'une classe ont tendance à traiter des types de données similaires (les membres) et un typedef est une opportunité pour attribuer un nom significatif dans le contexte de la classe. Cela facilite en fait la lisibilité dans les définitions des méthodes de classe.
et dans la mise en œuvre:
par opposition à:
ou:
la source
Un exemple concret pour clarifier la préoccupation. Imaginez que vous ayez une situation où vous avez deux bibliothèques
foo
etbar
chacune avec son propre espace de noms:Supposons maintenant que vous utilisez
foo
etbar
ensemble dans votre propre programme comme suit:À ce stade, tout va bien. Lorsque vous exécutez votre programme, il «fait quelque chose». Mais plus tard, vous mettez à jour
bar
et disons qu'il a changé pour ressembler à:À ce stade, vous obtiendrez une erreur de compilation:
Vous aurez donc besoin de faire un peu de maintenance pour clarifier que «a» signifiait
foo::a
. Ce n'est pas souhaitable, mais heureusement, c'est assez facile (il suffit d'ajouterfoo::
devant tous les appels àa
que le compilateur marque comme ambigu).Mais imaginez un scénario alternatif où la barre a changé à la place pour ressembler à ceci:
À ce stade, votre appel à
a(42)
se lie soudainement à labar::a
place defoo::a
et au lieu de faire «quelque chose», il fait «quelque chose de complètement différent». Aucun avertissement du compilateur ou quoi que ce soit. Votre programme commence juste silencieusement à faire quelque chose de complètement différent qu'auparavant.Lorsque vous utilisez un espace de noms, vous risquez un scénario comme celui-ci, c'est pourquoi les gens ne sont pas à l'aise avec les espaces de noms. Plus il y a de choses dans un espace de noms, plus le risque de conflit est grand, donc les gens pourraient être encore plus mal à l'aise d'utiliser l'espace de noms
std
(en raison du nombre de choses dans cet espace de noms) que les autres espaces de noms.En fin de compte, il s'agit d'un compromis entre l'écritabilité et la fiabilité / maintenabilité. La lisibilité peut également prendre en compte, mais je pouvais voir des arguments pour que cela aille dans les deux sens. Normalement, je dirais que la fiabilité et la maintenabilité sont plus importantes, mais dans ce cas, vous paierez constamment le coût d'écriture pour un impact relativement rare sur la fiabilité / maintenabilité. Le «meilleur» compromis déterminera votre projet et vos priorités.
la source
Un espace de noms est une étendue nommée. Les espaces de noms sont utilisés pour regrouper les déclarations liées et pour séparer les éléments séparés. Par exemple, deux bibliothèques développées séparément peuvent utiliser le même nom pour faire référence à des éléments différents, mais un utilisateur peut toujours utiliser les deux:
La répétition d'un nom d'espace de noms peut être une distraction pour les lecteurs et les écrivains. Par conséquent, il est possible d'indiquer que les noms d'un espace de noms particulier sont disponibles sans qualification explicite. Par exemple:
Les espaces de noms fournissent un outil puissant pour la gestion de différentes bibliothèques et de différentes versions de code. En particulier, ils offrent au programmeur des alternatives sur la façon explicite de faire référence à un nom non local.
Source: Un aperçu du langage de programmation C ++ par Bjarne Stroustrup
la source
Un exemple où
using namespace std
génère une erreur de compilation en raison de l'ambiguïté de count, qui est également une fonction de la bibliothèque d'algorithmes.la source
::count
--problème résolu. Habituellement, vous aurez plus de choses de l'espace de noms std qu'ailleurs, ergo garder la directive using namespace peut vous éviter de taper.Cela n'aggrave pas les performances de votre logiciel ou de votre projet. L'inclusion de l'espace de noms au début de votre code source n'est pas mauvaise. L'inclusion de l'
using namespace std
instruction varie en fonction de vos besoins et de la façon dont vous développez le logiciel ou le projet.Le
namespace std
contient les fonctions et variables standard C ++. Cet espace de noms est utile lorsque vous utilisez souvent les fonctions standard C ++.Certaines personnes avaient dit que c'était une mauvaise pratique d'inclure le
using namespace std
dans vos fichiers source parce que vous appelez à partir de cet espace de noms toutes les fonctions et variables. Lorsque vous souhaitez définir une nouvelle fonction avec le même nom qu'une autre fonction contenue dans le,namespace std
vous surchargez la fonction et cela pourrait produire des problèmes dus à la compilation ou à l'exécution. Il ne se compilera pas ou ne s'exécutera pas comme prévu.la source
Je ne pense pas que ce soit nécessairement une mauvaise pratique dans toutes les conditions, mais vous devez être prudent lorsque vous l'utilisez. Si vous écrivez une bibliothèque, vous devriez probablement utiliser les opérateurs de résolution de portée avec l'espace de noms pour empêcher votre bibliothèque de buter avec d'autres bibliothèques. Pour le code au niveau de l'application, je ne vois rien de mal à cela.
la source
"Pourquoi" utiliser l'espace de noms std; " considéré comme une mauvaise pratique en C ++? "
Je l'inverse: pourquoi la saisie de cinq caractères supplémentaires est-elle considérée comme lourde par certains?
Considérez par exemple l'écriture d'un logiciel numérique. Pourquoi envisagerais-je même de polluer mon espace de noms global en coupant "std :: vector" en "vector" alors que "vector" est l'un des concepts les plus importants du domaine problématique?
la source
cout << hex << setw(4) << i << endl;
est plus facile à lire questd::cout << std::hex << std::setw(4) << i << std::endl;
std::map<std::string,std::pair<std::string,std::string>>
est horrible par rapport àmap<string,pair<string,string>>
.Je suis d'accord avec les autres - cela demande des affrontements de noms, des ambiguïtés et le fait est que c'est moins explicite. Bien que je puisse voir l'utilisation de
using
, ma préférence personnelle est de la limiter. Je considérerais également fortement ce que certains ont souligné:Si vous voulez trouver un nom de fonction qui pourrait être un nom assez courant, mais que vous voulez seulement le trouver dans l'
std
espace de noms (ou l'inverse - vous voulez changer tous les appels qui ne sont pas dans l'espace de nomsstd
, l'espace de nomsX
, ...), alors comment proposez-vous de faire cela?Vous pourriez écrire un programme pour le faire, mais ne serait-il pas préférable de passer du temps à travailler sur votre projet lui-même plutôt que d'écrire un programme pour maintenir votre projet?
Personnellement, cela ne me dérange pas vraiment le
std::
préfixe. J'aime le look plus que de ne pas l'avoir. Je ne sais pas si c'est parce que c'est explicite et me dit "ce n'est pas mon code ... j'utilise la bibliothèque standard" ou si c'est autre chose, mais je pense que c'est plus joli. Cela peut être étrange étant donné que je ne suis entré que récemment dans C ++ (utilisé et continue de faire du C et d'autres langages beaucoup plus longtemps et C est mon langage préféré de tous les temps, juste au-dessus de l'assemblage).Il y a une autre chose bien qu'elle soit quelque peu liée à ce qui précède et à ce que d'autres soulignent. Bien que cela puisse être une mauvaise pratique, je réserve parfois
std::name
la version et le nom de la bibliothèque standard pour une implémentation spécifique au programme. Oui, en effet, cela pourrait vous mordre et vous mordre fort, mais tout se résume à ce que j'ai commencé ce projet à partir de zéro, et je suis le seul programmeur pour cela. Exemple: je surchargestd::string
et l'appellestring
. J'ai des ajouts utiles. Je l'ai fait en partie à cause de ma tendance C et Unix (+ Linux) vers les noms en minuscules.En plus de cela, vous pouvez avoir des alias d'espace de noms. Voici un exemple où il est utile qui pourrait ne pas avoir été mentionné. J'utilise la norme C ++ 11 et spécifiquement avec libstdc ++. Eh bien, il n'a pas de
std::regex
support complet . Bien sûr, il compile, mais il lève une exception dans le sens où il s'agit d'une erreur de la part du programmeur. Mais c'est le manque de mise en œuvre.Voici donc comment je l'ai résolu. Installez le regex de Boost et liez-le. Ensuite, je fais ce qui suit pour que lorsque libstdc ++ l'a complètement implémenté, je n'ai besoin que de supprimer ce bloc et le code reste le même:
Je ne dirai pas si c'est une mauvaise idée ou non. Je dirai cependant qu'il le garde propre pour mon projet et en même temps le rend spécifique: Vrai, je dois utiliser Boost, mais je l'utilise comme le libstdc ++ l'aura finalement. Oui, démarrer votre propre projet et commencer par une norme (...) au tout début va très loin dans la maintenance, le développement et tout ce qui est impliqué dans le projet!
Juste pour clarifier quelque chose: je ne pense pas que ce soit une bonne idée d'utiliser délibérément et plus spécifiquement le nom d'une classe / quoi que ce soit dans la STL . La chaîne est l'exception (ignorez le premier, ci-dessus ou deuxième ici, jeu de mots si vous devez) pour moi car je n'aimais pas l'idée de «chaîne».
En l'état, je suis toujours très partisan de C et partisan de C ++. Des détails épargnés, une grande partie de ce sur quoi je travaille correspond plus à C (mais c'était un bon exercice et un bon moyen de me faire a. Apprendre une autre langue et b. Essayer de ne pas être moins biaisé contre les objets / classes / etc qui est peut-être mieux énoncé moins fermés, moins arrogants et plus acceptants.). Mais ce qui est utile, c'est ce que certains ont déjà suggéré: j'utilise effectivement list (c'est assez générique, n'est-ce pas?), Et trie (même chose) pour en nommer deux qui provoqueraient un conflit de nom si je le faisais
using namespace std;
, et ainsi à cette fin, je préfère être spécifique, en contrôle et sachant que si je veux que ce soit l'utilisation standard, je devrai le préciser. En termes simples: aucune supposition autorisée.Et quant à faire partie des regex de Boost
std
. Je le fais pour une intégration future et - encore une fois, j'admets pleinement que c'est un parti pris - je ne pense pas que ce soit aussi moche queboost::regex:: ...
. En effet, c'est autre chose pour moi. Il y a beaucoup de choses en C ++ que je dois encore accepter pleinement dans les looks et les méthodes (un autre exemple: les modèles variadiques contre les arguments var [bien que j'admette que les modèles variadiques soient très très utiles!]). Même ceux que j'accepte, c'était difficile, et j'ai toujours des problèmes avec eux.la source
std
espace de noms est un comportement non défini et ne doit donc jamais être effectuée.D'après mon expérience, si vous avez plusieurs bibliothèques qui utilisent disons
cout
, mais à des fins différentes, vous pouvez utiliser le mauvaiscout
.Par exemple, si je tape
using namespace std;
etusing namespace otherlib;
et que je tape justecout
(qui se trouve être dans les deux), plutôt questd::cout
(ou'otherlib::cout'
), vous pouvez utiliser la mauvaise et obtenir des erreurs. C'est beaucoup plus efficace et efficient à utiliserstd::cout
.la source
Avec les identifiants importés non qualifiés, vous avez besoin d'outils de recherche externes comme grep pour savoir où les identifiants sont déclarés. Cela rend le raisonnement sur la correction du programme plus difficile.
la source
Cela dépend de l'endroit où il se trouve. S'il s'agit d'un en-tête commun, vous diminuez la valeur de l'espace de noms en le fusionnant dans l'espace de noms global. Gardez à l'esprit que cela pourrait être une bonne façon de créer des modules globaux.
la source
Il s'agit d'une mauvaise pratique, souvent appelée pollution globale des espaces de noms. Des problèmes peuvent survenir lorsque plusieurs espaces de noms ont le même nom de fonction avec signature, alors il sera ambigu pour le compilateur de décider lequel appeler et tout cela peut être évité lorsque vous spécifiez l'espace de noms avec votre appel de fonction comme
std::cout
. J'espère que cela t'aides. :)la source
Pour répondre à votre question, je le vois de cette façon pratiquement: beaucoup de programmeurs (pas tous) invoquent l'espace de noms std. Par conséquent, on devrait avoir l'habitude de NE PAS utiliser des choses qui empiètent ou utilisent les mêmes noms que ce qui se trouve dans l'espace de noms std. C'est beaucoup accordé, mais pas tellement par rapport au nombre de mots cohérents et de pseudonymes possibles qui peuvent être proposés à proprement parler.
Je veux dire vraiment ... dire "ne comptez pas sur le fait d'être présent", c'est simplement vous mettre en place pour compter sur le fait qu'il ne soit PAS présent. Vous allez constamment rencontrer des problèmes pour emprunter des extraits de code et les réparer constamment. Gardez simplement vos éléments définis par l'utilisateur et empruntés dans une portée limitée comme ils devraient l'être et soyez TRÈS épargnant avec les globaux (honnêtement, les globaux devraient presque toujours être un dernier recours aux fins de "compiler maintenant, sain d'esprit plus tard"). Vraiment, je pense que c'est un mauvais conseil de votre professeur car utiliser std fonctionnera à la fois pour "cout" et "std :: cout" mais NE PAS utiliser std ne fonctionnera que pour "std :: cout". Vous n'aurez pas toujours la chance d'écrire tout votre code.
REMARQUE: ne vous concentrez pas trop sur les problèmes d'efficacité avant d'avoir réellement appris un peu sur le fonctionnement des compilateurs. Avec un peu d'expérience en codage, vous n'avez pas besoin d'en apprendre beaucoup à leur sujet avant de réaliser à quel point ils sont capables de généraliser un bon code en quelque chose de simple. Tout aussi simple que si vous aviez écrit le tout en C. Un bon code n'est aussi complexe que nécessaire.
la source
<algorithm>
, par exemple), il semble un peu exagéré d'imaginer que les mêmes personnes pourraient éviter de manière fiable ces identifiants. Parcourez votre propre code et dites-moi que vous n'avez jamais appelé de variable ou de fonctioncount
. Oudistance
, oulog
,destroy
,launch
,visit
,beta
,sample
,messages
,clamp
,erase
,copy
,modulus
,left
, etc. Sans parler de tous les identifiants pas encorestd
qui va briser votre code lorsque C ++ 35 vient ...