web-dev-qa-db-fra.com

En C++, qu'est-ce qu'un "alias d'espace de nom"?

Qu'est-ce qu'un "alias d'espace de nom" en C++? Comment est-ce utilisé?

137
Martin B

Un alias d’espace de noms est un moyen pratique de faire référence à un nom d’espace de noms long par un nom différent et plus court.

Par exemple, supposons que vous souhaitiez utiliser les vecteurs numériques de uBLAS de Boost sans directive using namespace. Il est fastidieux d'indiquer à chaque fois l'espace de noms complet:

boost::numeric::ublas::vector<double> v;

Au lieu de cela, vous pouvez définir un alias pour boost::numeric::ublas - disons que nous voulons abréger cela en ublas:

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;
162
Martin B

Tout simplement, le #define ne fonctionnera pas.

namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }

Compile bien. Vous permet de contourner les conflits de noms d'espaces de noms/noms de classes.

namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }

Sur la dernière ligne, "Hmm: Oops" est une erreur de compilation. Le pré-processeur le modifie en Nope :: Oops, mais Nope est déjà un nom de classe.

7
user2168377

Notez également que les alias d’espace de noms et les directives d’utilisation sont résolus au moment de la compilation, pas au moment de l’exécution. (Plus spécifiquement, ce sont les deux outils utilisés pour indiquer au compilateur où chercher lors de la résolution de noms, s'il ne peut pas trouver un symbole particulier dans l'étendue actuelle ou dans l'une de ses portées parent.) compiler:

namespace A {
    int foo;
    namespace AA {
        int bar;
    } // namespace AA
    namespace AB {
        int bar;
    } // namespace AB
} // namespace A
namespace B {
    int foo;
    namespace BA {
        int bar;
    } // namespace BA
    namespace BB {
        int bar;
    } // namespace BB
} // namespace B

bool nsChooser1, nsChooser2;
// ...

// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;

// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
    if (nsChooser2)
        using namespace A::AA;
    else
        using namespace A::AB;
else
    if (nsChooser2)
        using namespace B::BA;
    else
        using namespace B::BB;

Or, un esprit curieux a peut-être remarqué que les variables constexpr sont également utilisées au moment de la compilation et se demande si elles peuvent être utilisées conjointement avec un alias ou une directive. À ma connaissance, ils ne peuvent pas, même si je peux me tromper à ce sujet. Si vous devez utiliser des variables de même nom dans des espaces de nom différents et choisir entre elles de manière dynamique, vous devrez utiliser des références ou des pointeurs.

// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);

int* bar;
if (nsChooser1) {
    if (nsChooser2) {
        bar = &A::AA::bar;
    } else {
        bar = &A::AB::bar;
    }
} else {
    if (nsChooser2) {
        bar = &B::BA::bar;
    } else {
        bar = &B::BB::bar;
    }
}

L’utilité de ce qui précède peut être limitée, mais elle devrait servir le but recherché.

(Toutes mes excuses pour les fautes que j'ai peut-être manquées dans ce qui précède.)

2
Justin Time

Plus d'informations sur ce sujet http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n

Il s’agit de choisir un alias pour un nom d’espace de nommage looong, tel que:

namespace SHORT = NamespaceFirst::NameSpaceNested::Meow

Ensuite, vous pouvez taper

typedef SHORT::mytype

au lieu de 

typedef NamespaceFirst::NameSpaceNested::Meow::mytype

Cette syntaxe ne fonctionne que pour les espaces de noms, ne peut pas inclure de classes, les types après le namespace NAME =

1
octoback

L'espace de noms est utilisé pour éviter les conflits de noms.

Par exemple:

namespace foo {
    class bar {
        //define it
    };
}

namespace baz {
    class bar {
        // define it
    };
}

Vous avez maintenant deux barres de noms de classes, complètement différentes et séparées grâce au namespacing.

Le "using namespace" que vous montrez est fait pour que vous n'ayez pas à spécifier l'espace de nommage pour utiliser des classes dans cet espace de nommage. c'est-à-dire que std :: string devient une chaîne.

ma ressource: https://www.quora.com/What-is-namespace-in-C++-1

0
mai