Come posso "non utilizzare" uno spazio dei nomi?


86

Uno dei capricci del mio sistema di sviluppo (Codegear C ++ Builder) è che alcune delle intestazioni generate automaticamente insistono per avere ...

using namespace xyzzy

... dichiarazioni in esse, che influiscono sul mio codice quando meno lo desidero o me lo aspetto.

C'è un modo in cui posso in qualche modo annullare / sovrascrivere una precedente istruzione "using" per evitarlo.

Può essere...

unusing namespace xyzzy;

3
Probabilmente dovresti aprire una segnalazione di bug con il loro sistema QC: qc.codegear.com
Kris Kumler

2
A proposito, quali intestazioni generate automaticamente sono queste?
Kris Kumler

2
Un giorno il C ++ avrà moduli e l'inclusione di codice in altro codice avrà costrutti di incapsulamento migliori. Fino ad allora, non c'è un modo semplice per aggirare questo problema. Considera l'idea di inserire il tuo codice in uno spazio dei nomi e di fare riferimento ad esso in questo modo.
Trevor Hickey,

Risposte:


59

No. Ma c'è una potenziale soluzione: se racchiudi la tua direttiva include in un suo spazio dei nomi, come questo ...

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

... quindi gli effetti di qualsiasi direttiva using all'interno di tale intestazione vengono neutralizzati.

Ciò potrebbe essere problematico in alcuni casi. Ecco perché ogni guida di stile C ++ consiglia vivamente di non inserire una direttiva "using namespace" in un file di intestazione.


1
In generale, questa è un'idea terribile . Le intestazioni C ++ non devono essere incluse in uno spazio dei nomi alternativo come è stato utilizzato qui.
Aaron

25
È una pessima idea includere anche una direttiva using in un file di intestazione. Questo semplicemente mitiga il problema.
Head Geek

4
Posizionare l'intestazione nel tuo spazio dei nomi non è una soluzione in quanto cambia il significato delle dichiarazioni in quella libreria. (-1)
Richard Corden

4
Dipende interamente da ciò che viene dichiarato nell'intestazione.
Head Geek

1
Ed è proprio per questo che si tratta di un comportamento indefinito.
Kris Kumler

56

No, non puoi disattivare uno spazio dei nomi. L'unica cosa che puoi fare è mettere l' using namespaceistruzione come un blocco per limitarne la portata.

Esempio:

{
    using namespace xyzzy;

} // stop using namespace xyzzy here

Forse puoi cambiare il modello utilizzato per le intestazioni generate automaticamente.


Puoi racchiudere un include in un blocco come questo?
Eclipse

Sì, questo non sarà possibile con il codice generato automaticamente. Byt mybe può cambiare il modello per il codice generato automaticamente?
jk.

Sì, questo non risolve davvero il problema che ha delle intestazioni che utilizzano spazi dei nomi.
Kip

Sfortunatamente, non è vero. Prova questo:
Adam

spazio dei nomi xyzzy {const int i {using namespace xyzzy; } // smetti di usare lo spazio dei nomi xyzzy qui
Adam

17

Potresti essere bloccato utilizzando spazi dei nomi espliciti sui conflitti:

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

10

Per riferimento futuro: dalla versione XE c'è un nuovo valore che puoi #define per evitare il temuto using namespace System;int include: DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE


Ma questo sembra non funzionare correttamente. Almeno in tutti i casi ho provato (con BCB6). Quindi ero solito ripiegare sull'aggiunta di spazi dei nomi espliciti sui conflitti e, peggio ancora, includere un'intestazione per evitare conflitti di nomi di tipo ...
Wolf

5

Che ne dici di usare sed, perl o qualche altro strumento da riga di comando come parte del tuo processo di compilazione per modificare gli header generati dopo che sono stati generati ma prima che vengano usati?


1

Un rapido esperimento con Visual Studio 2005 mostra che puoi racchiudere quelle intestazioni nel tuo spazio dei nomi con nome e quindi useciò di cui hai bisogno da questo spazio dei nomi (ma non usel'intero spazio dei nomi, poiché introdurrà lo spazio dei nomi che desideri nascondere.


1
Questo probabilmente causerà problemi di alterazione del nome se i file di intestazione sono dichiarazioni per una libreria. La compilazione avrà esito positivo, ma il linker non sarà in grado di trovare le definizioni, poiché sarebbero già state compilate in uno spazio dei nomi diverso.
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);
}

1
per favore spiega la tua risposta!
Mazz

è possibile utilizzare l'operatore di risoluzione dell'ambito per utilizzare un'altra variabile dello spazio dei nomi
Narendra kumawat

3
Non risponde alla domanda
MM
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.