En C ++, qu'est-ce qu'un «alias d'espace de noms»?

156

Qu'est-ce qu'un «alias d'espace de noms» en C ++? Comment est-ce utilisé?

Martin B
la source

Réponses:

186

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.

À titre d'exemple, disons que vous vouliez utiliser les vecteurs numériques de l'uBLAS de Boost sans using namespacedirective. Indiquer l'espace de noms complet à chaque fois est fastidieux:

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 ceci simplement en ublas:

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;
Martin B
la source
7
Pour éventuellement expliquer les votes négatifs, SO n'est pas et ne sera jamais un remplacement pour un bon manuel C ++. Un tel livre répondra à la question que vous avez posée. Et la "fonction" SO de répondre à vos propres questions ne doit pas être utilisée pour fournir des paraphrases de tels livres.
24
Aucune offense n'a été prise ... Juste pour expliquer pourquoi j'ai fait cela: d'après les commentaires de Joel dans le podcast, je crois comprendre que même les questions "d'entrée de gamme" étaient équitables sur SO, et qu'il était acceptable de poser une question et d'y répondre vous-même si ce contenu n'était pas encore sur SO sous une forme accessible. Mais apparemment, c'est mal vu?
Martin B du
1
Il y a certainement une étiquette pour répondre à votre propre question, pour éviter l'irritation; dans ce cas, il est assez évident que cela n'a jamais été une vraie question. Par exemple, stackoverflow.com/questions/494927/…
Marc Gravell
6
@Martin B: Je ne suis pas d'accord pour dire que c'est une question d'entrée de gamme - en fait, il y a eu des questions beaucoup plus évidentes posées dans le passé maintenant avec de nombreux votes. Cela dit, les gens peuvent penser que vous essayez simplement de vous faire une réputation. Une façon de contourner cela est de marquer une ou les deux questions / réponses comme "wiki communautaire". Personnellement, j'irais avec la question en tant que vous et répondrais en tant que communauté. Si la question est correcte, vous obtiendrez un retour sur investissement.
Richard Corden
1
Je pense que la question importante est de savoir si la question est réelle "- est-ce quelque chose qu'on vous a posé? Est-ce quelque chose que les gens veulent savoir? Est-ce quelque chose qui n'a pas déjà été posé et répondu sur SO? Si vous lisez le blog SO sur la communauté R publiant et répondant aux questions ici, notez qu'ils ont choisi les X principales questions que leur communauté n'arrêtait pas de poser , donc cela avait une pertinence dans le monde réel. Prendre des extraits aléatoires de connaissances spécifiques à une langue et les publier ici semble moins utile.
jalf
7

Tout simplement, la #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 collisions d'espace de nom / nom de classe.

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: Oups" est une erreur de compilation. Le pré-processeur le change en Nope :: Oops, mais Nope est déjà un nom de classe.

user2168377
la source
3
Qu'est-ce que #define? Peut-être que votre réponse fait référence à une version précédente de la question?
einpoklum
3

En savoir plus 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 noms long, tel que:

namespace SHORT = NamespaceFirst::NameSpaceNested::Meow

Puis plus tard, vous pouvez taperef

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, de types après le namespace NAME =

Kiriloff
la source
3

Notez également que les alias d'espace de noms et les directives d'utilisation sont résolus au moment de la compilation et non au moment de l'exécution. (Plus précisément, ce sont tous les deux des outils utilisés pour indiquer au compilateur où chercher ailleurs lors de la résolution de noms, s'il ne trouve pas un symbole particulier dans la portée actuelle ou l'une de ses portées parentes.) Par exemple, aucune de ces 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;

Maintenant, un esprit curieux peut avoir remarqué que des constexprvariables sont également utilisées au moment de la compilation, et se demander si elles peuvent être utilisées en conjonction avec un alias ou une directive. À ma connaissance, ils ne le peuvent pas, bien que je puisse me tromper à ce sujet. Si vous avez besoin de travailler avec des variables portant le même nom dans différents espaces de noms et de 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 l'objectif.

(Mes excuses pour les fautes de frappe que j'ai pu manquer dans ce qui précède.)

Justin Time - Réintégrer Monica
la source
0

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 nom de classes, qui sont complètement différentes et séparées grâce à l'espacement des noms.

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

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

mai
la source