Como posso “desusar” um namespace?

86

Uma das peculiaridades do meu sistema de desenvolvimento (Codegear C ++ Builder) é que alguns dos cabeçalhos gerados automaticamente insistem em ter ...

using namespace xyzzy

... declarações neles, que afetam meu código quando eu menos quero ou espero.

Existe uma maneira de cancelar / substituir de alguma forma uma declaração "usando" anterior para evitar isso.

Talvez...

unusing namespace xyzzy;
Roddy
fonte
3
Você provavelmente deve abrir um relatório de bug com o sistema QC deles: qc.codegear.com
Kris Kumler
2
BTW, quais cabeçalhos gerados automaticamente são esses?
Kris Kumler,
2
Um dia, o C ++ terá módulos, e incluir código em outro código terá melhores construções de encapsulamento. Até então, não existe uma maneira fácil de contornar isso. Considere colocar seu próprio código em um namespace e se referir a ele dessa forma.
Trevor Hickey

Respostas:

59

Não. Mas há uma solução potencial: se você colocar sua diretiva de inclusão em um namespace próprio, como este ...

namespace codegear {
    #include "codegear_header.h"
} // namespace codegear

... então, os efeitos de qualquer uso de diretivas dentro desse cabeçalho são neutralizados.

Isso pode ser problemático em alguns casos. É por isso que todo guia de estilo C ++ recomenda fortemente não colocar uma diretiva "using namespace" em um arquivo de cabeçalho.

Head Geek
fonte
1
Em geral, essa é uma ideia terrível . Os cabeçalhos C ++ não devem ser incluídos em um namespace alternativo como foi usado aqui.
Aaron,
24
É uma péssima ideia incluir uma diretiva using em um arquivo de cabeçalho também. Isso simplesmente atenua o problema.
Head Geek,
4
Colocar o cabeçalho em seu próprio namespace não é uma solução, pois muda o significado das declarações nessa biblioteca. (-1)
Richard Corden,
4
Isso depende inteiramente do que está sendo declarado no cabeçalho.
Head Geek,
1
É exatamente por isso que é um comportamento indefinido.
Kris Kumler,
56

Não, você não pode cancelar o uso de um namespace. A única coisa que você pode fazer é colocar a using namespaceinstrução -um bloco para limitar seu escopo.

Exemplo:

{
    using namespace xyzzy;

} // stop using namespace xyzzy here

Talvez você possa alterar o modelo que é usado para seus cabeçalhos gerados automaticamente.

jk.
fonte
Você pode embrulhar um include em um bloco como este?
Eclipse,
Sim, isso não acontecerá com o código gerado automaticamente. Por que ele pode alterar o modelo para o código gerado automaticamente?
jk.
Sim, isso realmente não resolve o problema que ele está tendo de cabeçalhos usando namespaces.
Kip,
Infelizmente, isto não é verdade. Tente isto:
Adam,
namespace xyzzy {const int i {using namespace xyzzy; } // pare de usar o namespace xyzzy aqui
Adam,
17

Você pode ficar preso usando namespaces explícitos em conflitos:

string x; // Doesn't work due to conflicting declarations
::string y; // use the class from the global namespace
std::string z; // use the string class from the std namespace
Eclipse
fonte
10

Para referência futura: desde a versão XE, há um novo valor que você pode #define para evitar o temido using namespace System;no include: DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE

cdelacroix
fonte
Mas isso parece não funcionar corretamente. Pelo menos em todos os casos tentei (com BCB6). Eu costumava voltar a adicionar namespaces explícitos em conflitos e - pior ainda - incluir um cabeçalho para evitar conflitos de nome de tipo ...
Wolf
6

Que tal usar sed, perl ou alguma outra ferramenta de linha de comando como parte de seu processo de construção para modificar os cabeçalhos gerados depois que eles são gerados, mas antes de serem usados?


fonte
1

Um experimento rápido com o Visual Studio 2005 mostra que você pode incluir esses cabeçalhos em seu próprio namespace nomeado e, em seguida, o useque você precisa desse namespace (mas não useo namespace inteiro, pois ele apresentará o namespace que você deseja ocultar.

Kasprzol
fonte
1
Isso provavelmente causará problemas de alteração de nome se os arquivos de cabeçalho forem declarações para uma biblioteca. A compilação será bem-sucedida, mas o vinculador não conseguirá localizar as definições, pois elas já teriam sido compiladas em um namespace diferente.
Eclipse,
-1
#include<iostream>
#include<stdio.h>
namespace namespace1 {
    int t = 10;
}
namespace namespace2 {
    int t = 20;
}
int main() {
using namespace namespace1;
    printf("%d" , t);
    printf("%d" , namespace2::t);
}
Narendra Kumawat
fonte
1
explique sua resposta!
Mazz
você pode usar o operador de resolução de escopo para usar outra variável de namespace
Narendra kumawat
3
Não responde à questão
MM