No C ++, o que é um "alias de espaço para nome"?


156

O que é um "alias de espaço para nome" em C ++? Como isso é usado?

Respostas:


186

Um alias de namespace é uma maneira conveniente de se referir a um nome de namespace longo por um nome menor e diferente.

Como exemplo, digamos que você queira usar os vetores numéricos do uBLAS do Boost sem uma using namespacediretiva. Declarar o espaço para nome completo toda vez é complicado:

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

Em vez disso, você pode definir um alias para boost::numeric::ublas- digamos que queremos abreviar isso para apenas ublas:

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;

7
Para possivelmente explicar as votações negativas, o SO não é e nunca será um substituto para um bom livro C ++. A pergunta que você fez será respondida por qualquer livro desse tipo. E o SO "recurso" de responder suas próprias perguntas não deve ser usado para fornecer paráfrases de tais livros.

24
Sem ofensas ... Apenas para explicar por que fiz isso: entendi pelos comentários de Joel no podcast que mesmo as perguntas "básicas" eram um jogo justo no SO, e que era aceitável fazer uma pergunta e respondê-la você mesmo se esse conteúdo ainda não estava disponível no SO de forma acessível. Mas, aparentemente, isso é desaprovado?
Martin B

1
Certamente há uma etiqueta para responder à sua própria pergunta, para evitar irritações; neste caso, é bastante óbvio que nunca foi uma pergunta real. Por exemplo, stackoverflow.com/questions/494927/…
Marc Gravell

6
@ Martin B: Não concordo que esta seja uma pergunta de nível básico - de fato, houve perguntas muito mais óbvias no passado agora com muitos votos. Dito isto, as pessoas podem sentir que você está simplesmente tentando ganhar reputação por si mesmo. Uma maneira de contornar isso é marcar uma ou as duas perguntas / respostas como "wiki da comunidade". Pessoalmente, eu faria perguntas como você e responderia como comunidade. Se a pergunta tiver mérito, você obterá o ROI.
Richard Corden

1
Eu acho que a pergunta importante é se a pergunta é real "- é algo que você já perguntou? É algo que as pessoas querem saber? É algo que ainda não foi perguntado e respondido no SO? Se você ler a postagem do blog SO sobre a comunidade R postando e respondendo perguntas aqui, observe que eles escolheram as principais perguntas X que sua comunidade realmente fazia, por isso tinha relevância no mundo real. menos útil.
jalf

7

Simplesmente, o #define não funcionará.

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

Compila bem. Permite contornar colisões de namespace / nome de classe.

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

Na última linha, "Hmm: Opa" é um erro de compilação. O pré-processador o altera para Nope :: Oops, mas Nope já é um nome de classe.


3
O que definir? Talvez sua resposta se refira a uma versão anterior da pergunta?
einpoklum


3

Observe também que os aliases de namespace e o uso de diretivas são resolvidos no tempo de compilação, não no tempo de execução. (Mais especificamente, as duas ferramentas são usadas para informar ao compilador onde mais procurar ao resolver nomes, se ele não conseguir encontrar um símbolo específico no escopo atual ou em qualquer um de seus escopos pai.) Por exemplo, nenhum deles será 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;

Agora, uma mente curiosa pode ter notado que as constexprvariáveis ​​também são usadas em tempo de compilação e se pergunta se elas podem ser usadas em conjunto com um alias ou uma diretiva. Que eu saiba, eles não podem, embora eu possa estar errado sobre isso. Se você precisar trabalhar com variáveis ​​nomeadas de forma idêntica em diferentes espaços para nome e escolher entre elas dinamicamente, seria necessário usar referências ou ponteiros.

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

A utilidade do acima exposto pode ser limitada, mas deve servir ao propósito.

(Minhas desculpas por quaisquer erros de digitação que eu possa ter perdido no item acima.)


0

O espaço para nome é usado para evitar conflitos de nome.

Por exemplo:

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

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

Agora você tem duas barras de nomes de classes, que são completamente diferentes e separadas graças ao espaço para nome.

O "using namespace" que você mostra é para que você não precise especificar o namespace para usar as classes nesse namespace. ou seja, std :: string se torna string.

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.