En C ++, ¿qué es un "alias de espacio de nombres"?


156

¿Qué es un "alias de espacio de nombres" en C ++? ¿Cómo se usa?

Respuestas:


186

Un alias de espacio de nombres es una forma conveniente de referirse a un nombre de espacio de nombres largo con un nombre diferente y más corto.

Como ejemplo, supongamos que desea utilizar los vectores numéricos de uBLAS de Boost sin una using namespacedirectiva. Establecer el espacio de nombres completo cada vez es engorroso:

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

En su lugar, puede definir un alias para boost::numeric::ublas- digamos que queremos abreviar esto para simplemente ublas:

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;

77
Para explicar posiblemente los votos negativos, SO no es y nunca será un reemplazo para un buen libro de texto de C ++. La pregunta que planteó será respondida por cualquiera de esos libros. Y la "característica" SO de responder sus propias preguntas no debe usarse para proporcionar paráfrasis de tales libros.

24
Sin ofender ... Solo para explicar por qué hice esto: por los comentarios de Joel en el podcast entendí que incluso las preguntas de "nivel de entrada" eran un juego justo en SO, y que era aceptable hacer una pregunta y responderla usted mismo si ese contenido aún no estaba en SO de forma accesible. Pero al parecer, esto está mal visto?
Martin B

1
Ciertamente, hay una etiqueta para responder a su propia pregunta, para evitar la irritación; en este caso, es bastante obvio que nunca fue una pregunta real. Por ejemplo, stackoverflow.com/questions/494927/…
Marc Gravell

66
@ Martin B: No estoy de acuerdo con que esta sea una pregunta de nivel de entrada; de hecho, ha habido preguntas mucho más obvias en el pasado ahora con muchos votos. Dicho esto, la gente puede sentir que simplemente estás tratando de ganar reputación por ti mismo. Una forma de evitar esto es marcar una o ambas preguntas / respuestas como "wiki de la comunidad". Personalmente iría con preguntas como tú y contesto como comunidad. Si la pregunta tiene merrit, obtendrá ROI.
Richard Corden el

1
Creo que la pregunta importante es si la pregunta es real ": ¿es algo que le han preguntado? ¿Es algo que la gente quiere saber? ¿Es algo que aún no se ha preguntado y respondido en SO? Si lee En la publicación del blog SO sobre la comunidad R publicando y respondiendo preguntas aquí, tenga en cuenta que escogieron las X preguntas principales que su comunidad en realidad seguía haciendo , por lo que tenía relevancia en el mundo real. menos útil.
jalf

7

Simplemente, el #define no funcionará.

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

Compila bien. Le permite evitar colisiones de nombres de clase / espacio de nombres.

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

En la última línea, "Hmm: Vaya" es un error de compilación. El preprocesador lo cambia a Nope :: Oops, pero Nope ya es un nombre de clase.


3
¿Qué #define? ¿Quizás su respuesta se refiere a una versión anterior de la pregunta?
einpoklum

3

Más sobre este tema http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n

Se trata de elegir un alias para un nombre de espacio de nombres muy largo, como:

namespace SHORT = NamespaceFirst::NameSpaceNested::Meow

Luego, más tarde, puede escribir def

typedef SHORT::mytype

en vez de

typedef NamespaceFirst::NameSpaceNested::Meow::mytype

Esta sintaxis solo funciona para espacios de nombres, no puede incluir clases, tipos después de namespace NAME =


3

También tenga en cuenta que los alias de espacio de nombres y el uso de directivas se resuelven en tiempo de compilación, no en tiempo de ejecución. (Más específicamente, ambas herramientas se usan para indicarle al compilador dónde más buscar al resolver nombres, si no puede encontrar un símbolo en particular en el alcance actual o en cualquiera de sus ámbitos principales). Por ejemplo, ninguno de estos compilar:

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;

Ahora, una mente curiosa puede haber notado que las constexprvariables también se usan en el momento de la compilación, y se pregunta si pueden usarse junto con un alias o una directiva. Que yo sepa, no pueden, aunque puedo estar equivocado sobre esto. Si necesita trabajar con variables con nombres idénticos en diferentes espacios de nombres y elegir dinámicamente entre ellas, deberá usar referencias o punteros.

// 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;
    }
}

La utilidad de lo anterior puede ser limitada, pero debe cumplir el propósito.

(Mis disculpas por cualquier error tipográfico que me haya perdido en lo anterior).


0

El espacio de nombres se usa para evitar conflictos de nombres.

Por ejemplo:

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

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

Ahora tiene una barra de nombre de dos clases, que son completamente diferentes y separadas gracias al espacio de nombres.

El "uso del espacio de nombres" que muestra es para que no tenga que especificar el espacio de nombres para usar clases dentro de ese espacio de nombres. es decir, std :: string se convierte en string.

mi recurso: https://www.quora.com/What-is-namespace-in-C++-1

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.