Les déclarations using permettent d'utiliser un identificateur d'un espace de nommage de manière simplifiée, sans avoir à spécifier son nom complet (c'est-à-dire le nom de l'espace de nommage suivi du nom de l'identificateur).
Syntaxe des déclarations using.
La syntaxe des déclarations using est la suivante :
using identificateur;
où identificateur est le nom complet de l'identificateur à utiliser, avec qualification d'espace de nommage.
Exemple 11-7. Déclaration using.
namespace A
 int i; // Déclare A::i.
 int j; // Déclare A::j.
void f(void)
 using A::i; // A::i peut être utilisé sous le nom i.
 i=1; // Équivalent à A::i=1.
 j=1; // Erreur ! j n'est pas défini !
 return ;
Les déclarations using permettent en fait de déclarer des alias des identificateurs. Ces alias doivent être considérés exactement comme des déclarations normales. Cela signifie qu'ils ne peuvent être déclarés plusieurs fois que lorsque les déclarations multiples sont autorisées (déclarations de variables ou de fonctions en dehors des classes), et de plus ils appartiennent à l'espace de nommage dans lequel ils sont définis.
Exemple 11-8. Déclarations using multiples.
namespace A
 int i;
 void f(void)
namespace B
 using A::i; // Déclaration de l'alias B::i, qui représente A::i.
 using A::i; // Légal : double déclaration de A::i.
 using A::f; // Déclare void B::f(void),
 // fonction identique à A::f.
int main(void)
 B::f(); // Appelle A::f.
 return 0;
L'alias créé par une déclaration using permet de référencer uniquement les identificateurs qui sont visibles au moment où la déclaration using est faite. Si l'espace de nommage concerné par la déclaration using est étendu après cette dernière, les nouveaux identificateurs de même nom que celui de l'alias ne seront pas pris en compte.
Exemple 11-9. Extension de namespace après une déclaration using.
namespace A
 void f(int);
using A::f; // f est synonyme de A::f(int).
namespace A
 void f(char); // f est toujours synonyme de A::f(int),
 // mais pas de A::f(char).
void g()
 f('a'); // Appelle A::f(int), même si A::f(char)
 // existe.
Si plusieurs déclarations locales et using déclarent des identificateurs de même nom, ou bien ces identificateurs doivent tous se rapporter au même objet, ou bien ils doivent représenter des fonctions ayant des signatures différentes (les fonctions déclarées sont donc surchargées). Dans le cas contraire, des ambiguïtés peuvent apparaître et le compilateur signale une erreur lors de la déclaration using.
Exemple 11-10. Conflit entre déclarations using et identificateurs locaux.
namespace A
 int i;
 void f(int);
void g(void)
 int i; // Déclaration locale de i.
 using A::i; // Erreur : i est déjà déclaré.
 void f(char); // Déclaration locale de f(char).
 using A::f; // Pas d'erreur, il y a surcharge de f.
 return ;
Utilisation des déclarations using dans les classes.
Une déclaration using peut être utilisée dans la définition d'une classe. Dans ce cas, elle doit se rapporter à une classe de base de la classe dans laquelle elle est utilisée. De plus, l'identificateur donné à la déclaration using doit être accessible dans la classe de base (c'est-à-dire de type protected ou public).
Exemple 11-11. Déclaration using dans une classe.
namespace A
 float f;
class Base
 int i;
public:
 int j;
class Derivee : public Base
 using A::f; // Illégal : f n'est pas dans une classe
 // de base.
 using Base::i; // Interdit : Derivee n'a pas le droit
 // d'utiliser Base::i.
public:
 using Base::j; // Légal.
Dans l'exemple précédent, seule la troisième déclaration est valide, parce que c'est la seule qui se réfère à un membre accessible de la classe de base. Le membre j déclaré sera donc un synonyme de Base::j dans la classe Derivee.
En général, les membres des classes de base sont accessibles directement. Quelle est donc l'utilité des déclarations using dans les classes ? En fait, elles peuvent être utilisées pour rétablir les droits d'accès, modifiés par un héritage, à des membres de classes de base. Pour cela, il suffit de placer la déclaration using dans une zone de déclaration du même type que celle dans laquelle le membre se trouvait dans la classe de base. Cependant, comme on l'a vu ci-dessus, une classe ne peut pas rétablir les droits d'accès d'un membre de classe de base déclaré en zone private.
Exemple 11-12. Rétablissement de droits d'accès à l'aide d'une directive using.
class Base
public:
 int i;
 int j;
class Derivee : private Base
public:
 using Base::i; // Rétablit l'accessibilité sur Base::i.
protected:
 using Base::i; // Interdit : restreint l'accessibilité
 // sur Base::i autrement que par héritage.
Quand une fonction d'une classe de base est introduite dans une classe dérivée à l'aide d'une déclaration using, et qu'une fonction de même nom et de même signature est définie dans la classe dérivée, cette dernière fonction surcharge la fonction de la classe de base. Il n'y a pas d'ambiguïté dans ce cas.

Programmation C-C++/Les espaces de nommage/Directive using

La directive using permet d'utiliser, sans spécification d'espace de nommage, non pas un identificateur comme dans le cas de la déclaration using, mais tous les identificateurs de cet espace de nommage.
La syntaxe de la directive using est la suivante :
using namespace nom;
où nom est le nom de l'espace de nommage dont les identificateurs doivent être utilisés sans qualification complète.
Exemple 11-13. Directive using.
namespace A
 int i; // Déclare A::i.
 int j; // Déclare A::j.
void f(void)
 using namespace A; // On utilise les identificateurs de A.
 i=1; // Équivalent à A::i=1.
 j=1; // Équivalent à A::j=1.
 return ;
Après une directive using, il est toujours possible d'utiliser les noms complets des identificateurs de l'espace de nommage, mais ce n'est plus nécessaire. Les directives using sont valides à partir de la ligne où elles sont déclarées jusqu'à la fin du bloc de portée courante. Si un espace de nommage est étendu après une directive using, les identificateurs définis dans l'extension de l'espace de nommage peuvent être utilisés exactement comme les identificateurs définis avant la directive using (c'est-à-dire sans qualification complète de leurs noms).
Exemple 11-14. Extension de namespace après une directive using.
namespace A
 int i;
using namespace A;
namespace A
 int j;
void f(void)
 i=0; // Initialise A::i.
 j=0; // Initialise A::j.
 return ;
Il se peut que lors de l'introduction des identificateurs d'un espace de nommage par une directive using, des conflits de noms apparaissent. Dans ce cas, aucune erreur n'est signalée lors de la directive using. En revanche, une erreur se produit si un des identificateurs pour lesquels il y a conflit est utilisé.
Exemple 11-15. Conflit entre directive using et identificateurs locaux.
namespace A
 int i; // Définit A::i.
namespace B
 int i; // Définit B::i.
 using namespace A; // A::i et B::i sont en conflit.
 // Cependant, aucune erreur n'apparaît.
void f(void)
 using namespace B;
 i=2; // Erreur : il y a ambiguïté.
 return ;

Programmation C-C++/Les templates/Généralités