111 votes

Quelle est la portée de la déclaration "using" en C++ ?

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, cela va-t-il injecter ces déclarations 'using' dans tous les fichiers cpp qui incluent l'en-tête ?

21 votes

Juste au cas où ce ne serait pas clair d'après les autres réponses ici : - Ne pas mettre un using déclaration (ou using ) au niveau du fichier dans un fichier/en-tête d'inclusion ! Cela va causer des maux de tête aux utilisateurs de l'en-tête.

1 votes

En fait, il ne faut pas mettre un using déclaration (a fortiori directive ) dans un en-tête du tout , même dans un espace de nom ! Voir portée de la déclaration d'utilisation dans un espace de nom pour les problèmes que cela entraîne.

0 votes

@NilsvonBarth : C'est un peu trop simplifié. En utilisant using dans la classe et la fonction est sûre en ce qui concerne le problème discuté.

124voto

Eclipse Points 27662

Il n'y a rien de spécial dans les fichiers d'en-tête qui permettrait de conserver la fonction using la déclaration de sortie. Il s'agit d'une simple substitution de texte avant même que la compilation ne commence.

Vous pouvez limiter un using à une portée :

void myFunction()
{
   using namespace std; // only applies to the function's scope
   vector<int> myVector;
}

15 votes

Je n'ai jamais pensé que je pouvais l'utiliser à l'intérieur d'une fonction !

1 votes

J'ai un tas d'espaces de noms qui sont tous utilisés par un fichier de type "conglomérateur", et le test unitaire de gmock était très fastidieux parce que chaque test utilisait des choses d'un espace de noms spécifique, et je pensais que je devais qualifier chaque variable. Utilisation de using à l'intérieur d'une fonction (ou même d'un gtest TEST macro !) rend ma vie tellement plus agréable !

65voto

Jeremy Ruten Points 59989

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. Ainsi, l'inclusion d'un fichier qui a un using a exactement le même effet que de placer la using en haut de chaque fichier qui inclut ce fichier d'en-tête.

56 votes

... ce qui est généralement une mauvaise chose.

18 votes

Mais si vous mettez le using à l'intérieur d'une déclaration namespace elle est limitée à l'étendue de cet espace de noms, et est donc généralement acceptable (avec les réserves habituelles sur vos besoins et votre style particuliers).

1 votes

...mais si vous mettez l'utilisation à l'intérieur d'un espace de nom, assurez-vous que vous ne le faites pas pour essayer de contourner quelque chose qui est normalement une mauvaise idée, comme vous ne pouvez pas encaisser les méthodes de classe déclarées en dehors de l'espace de nom Y à l'intérieur de l'autre espace de nom X, juste pour que vous puissiez utiliser localement l'espace de nom X. C'est pourquoi nous avons l'utilisation des espaces de nom : : résolveurs en premier lieu. Si c'est un si gros problème de typage, il faut utiliser une macro (qui peut facilement conduire à des odeurs de code) ou mieux encore, l'isoler dans sa propre source .cpp où vous n'utiliserez l'espace de nom que là.

58voto

dagorym Points 2025

La portée de l'instruction using dépend de l'endroit où elle se trouve dans le code :

  • Placé en haut d'un dossier, il a une portée sur l'ensemble de ce dossier.
  • Si c'est un fichier d'en-tête, il aura une portée dans tous les fichiers qui incluent cet en-tête. En général, il s'agit de " pas une bonne idée "car il peut avoir des effets secondaires inattendus
  • Sinon, le en utilisant a une portée dans le bloc qui la contient, depuis le moment où elle se produit jusqu'à la fin du bloc. Si elle est placée dans une méthode, elle aura une portée dans cette méthode. Si elle est placée à l'intérieur d'une définition de classe, elle aura une portée à l'intérieur de cette classe.

6 votes

Je pensais qu'il n'était pas possible d'ajouter une using dans la portée de la classe... ? J'ai eu la même question que l'OP à cause de cela car je voulais éviter de taper std:: partout. J'ai des cours qui utilisent beaucoup de vecteurs avec des pointeurs intelligents et les cinq caractères std:: préfixe ajoute beaucoup de longueur de ligne - ce qui, je trouve, se lit moins bien. Je me demandais donc si un using à l'intérieur de l'espace de nom contenant la classe est acceptable ? (Même si c'est dans un en-tête.)

6 votes

Qu'en est-il si elle est placée dans le cadre d'une namespace { ... } ?

0 votes

Vous pouvez donc tout à fait écrire : { using namespace blabla ; class blah {} ; } et cet usage ne s'appliquera qu'à la classe ?

8voto

JohnMcG Points 5062

La portée est celle dans laquelle se trouve la déclaration using.

S'il s'agit d'un champ d'application mondial, alors il sera à 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 inclut l'en-tête.

Le conseil général est donc le suivant éviter d'utiliser les déclarations dans la portée globale des fichiers d'en-tête .

3 votes

Ce n'est pas assez fort. Remplacez éviter par ne pas

1 votes

Mais éviter est plus fort que ne pas le faire. "Éviter de heurter les autres voitures"

6voto

James Curran Points 55356

Dans le cas cité, le fichier ("unité de traduction"), ce qui signifie oui, tous les fichiers qui l'incluent.

Vous pouvez également placer la déclaration using à l'intérieur de la classe, auquel cas elle ne s'applique qu'à cette classe.

En général, si vous devez spécifier un espace de noms dans un en-tête, il est souvent préférable de qualifier complètement chaque identifiant nécessaire.

0 votes

Notez que le using dans une classe ne se comporte pas de la même manière qu'à l'extérieur d'une classe - par exemple, vous ne pouvez pas l'utiliser pour apporter des informations sur l'état de la classe. cout au lieu de std::cout dans la portée de la classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X