J'utilise la déclaration «using» en C ++ pour ajouter std :: string et std :: vector à l'espace de noms local (pour éviter de taper des «std ::» inutiles).
using std::string;
using std::vector;
class Foo { /*...*/ };
Quelle est la portée de cette déclaration? Si je fais cela dans un en-tête, injectera-t-il ces déclarations «using» dans chaque fichier cpp qui inclut l'en-tête?
using
déclaration (ouusing
directive) à la portée du fichier dans un fichier / en-tête d'inclusion! Cela causera des maux de tête aux utilisateurs de l'en-tête.using
déclaration (a fortiori directive ) dans un en- tête du tout , même dans un espace de noms! Voir la portée de la déclaration d'utilisation dans un espace de noms pour les problèmes que cela provoque.using
dans la portée de la classe et de la fonction est sûre par rapport au problème discuté.Réponses:
Lorsque vous #incluez un fichier d'en-tête en C ++, il place tout le contenu du fichier d'en-tête à l'endroit où vous l'avez inclus dans le fichier source. Donc, inclure un fichier qui a une
using
déclaration a exactement le même effet de placer lausing
déclaration en haut de chaque fichier qui inclut ce fichier d'en-tête.la source
using
déclaration dans un,namespace
elle est limitée à la portée de cet espace de noms, donc c'est généralement OK (avec les mises en garde habituelles sur vos besoins et votre style particuliers).Il n'y a rien de spécial dans les fichiers d'en-tête qui empêcherait la
using
déclaration. C'est une simple substitution de texte avant même que la compilation ne commence.Vous pouvez limiter une
using
déclaration à une portée:la source
using
intérieur d'une fonction (ou même d'uneTEST
macro gtest !) Rend ma vie tellement meilleure!La portée de l'instruction using dépend de son emplacement dans le code:
la source
using
instruction dans la portée de la classe ...? J'avais la même question que l'OP à cause de cela car je voulais éviter de taperstd::
partout. J'ai des classes qui utilisent beaucoup de vecteurs avec des pointeurs intelligents et lestd::
préfixe à cinq caractères ajoute beaucoup de longueur de ligne - ce que je trouve pire. Donc je me demandais si uneusing
directive dans l'espace de noms contenant la classe était ok? (Même si dans un en-tête.)namespace { ... }
?La portée est quelle que soit la portée de la déclaration using.
S'il s'agit d'une portée mondiale, alors ce sera une portée mondiale. S'il est dans la portée globale d'un fichier d'en-tête, alors il sera dans la portée globale de chaque fichier source qui comprend l'en-tête.
Ainsi, le conseil général est d' éviter d'utiliser des déclarations dans la portée globale des fichiers d'en-tête .
la source
Dans le cas cité, le fichier ("unité de traduction"), ce qui signifie oui, chaque fichier qui le comprend.
Vous pouvez également placer l'instruction using à l'intérieur de la classe, auquel cas, elle n'est effective que pour cette classe.
En règle générale, si vous devez spécifier un espace de noms dans un en-tête, il est souvent préférable de simplement qualifier complètement chaque identifiant nécessaire.
la source
using
déclaration dans une classe ne se comporte pas de la même manière qu'en dehors d'une classe - par exemple, vous ne pouvez pas l'utiliser pour amener à lacout
place destd::cout
dans la portée de la classe.C'est correct. La portée est le module qui utilise la
using
déclaration. Si des fichiers d'en-tête inclus dans un module ont desusing
déclarations, la portée de ces déclarations sera ce module, ainsi que tous les autres modules qui incluent les mêmes en-têtes.la source
Il y a quelques commentaires qui sont plutôt sans réserve quand ils disent "Ne pas". C'est trop sévère, mais il faut comprendre quand ça va.
L'écriture
using std::string
n'est jamais OK. Ecrireusing ImplementationDetail::Foo
dans votre propre en-tête, lorsque cet en-tête déclare ImplementationDetail :: Foo peut être OK, plus encore si la déclaration using se produit dans votre espace de noms. Par exemplela source
MyNS::Foo
using boost::posix_time::ptime
. Bien sûr, l'utilisateur peut écrire,MyNS::ptime
mais ce n'est pas la fin du monde, et pourrait être compensé par la commodité de pouvoir avoir des fonctions commeMyFunction(ptime a, ptime b)
.using std::string
ça ne va jamais? Même dans votre propre espace de noms pour enregistrer beaucoup destd::
préfixes?