2010-07-20 6 views
24

Ho un enum in un namespace e mi piacerebbe usarlo come se fosse in un namespace diverso. Intuitivamente, ho pensato che avrei potuto usare "using" o "typedef" per ottenere questo risultato, ma nessuno dei due ha funzionato. Frammento di codice per dimostrarlo, testato su GCC e Sun CC:Come si importa un enum in uno spazio dei nomi diverso in C++?

namespace foo 
{ 

enum bar { 
    A 
}; 

} 

namespace buzz 
{ 
// Which of these two methods I use doesn't matter, 
// the results are the same. 
using foo::bar; 
//typedef foo::bar bar; 
} 

int main() 
{ 
    foo::bar f; // works 
    foo::bar g = foo::A; // works 

    buzz::bar x; // works 
    //buzz::bar y = buzz::A; // doesn't work 
    buzz::bar z = foo::A; 
} 

Il problema è che l'enum in sé è importata, ma nessuno dei suoi elementi. Sfortunatamente, non posso modificare l'enum originale per essere racchiuso in uno spazio dei nomi fittizio extra o in una classe senza rompere un sacco di altri codici esistenti. La soluzione migliore che posso pensare è quello di riprodurre manualmente l'enum:

namespace buzz 
{ 
enum bar 
{ 
    A = foo::A 
}; 
} 

Ma viola la DRY principle. C'è un modo migliore?

+0

"Ma viola il principio ASCIUTTO." In questo caso, riconsidererei l'utilizzo del principio. "C'è un modo migliore?" le enumerazioni (sfortunatamente) non sono scope, ma puoi mettere elementi enum in struct o namespace aggiuntivi. – SigTerm

+0

Sfortunatamente molti altri codici si basano sull'enum originale non essendo in un altro ambito:/ –

+1

Whoa ... Se qualcuno mi avesse chiesto qualcosa del genere, avrei risposto che avrebbe dovuto funzionare. Grazie per aver rivelato questo angolo oscuro di C++ ... +1. – paercebal

risposta

22

Avvolgi lo spazio dei nomi esistente in uno spazio dei nomi annidato che quindi "utilizzi" nello spazio dei nomi originale.

namespace foo 
{ 
    namespace bar_wrapper { 
     enum bar { 
      A 
     }; 
    } 
    using namespace bar_wrapper; 
} 

namespace buzz 
{ 
    using namespace foo::bar_wrapper; 
} 
5

Il problema qui è che la dichiarazione using attira solo il nome dell'enum e non i nomi dei suoi valori. Gli Enum non sono ambiti e non portano i nomi degli enumeratori . Non penso sia possibile importare i valori enum da soli. Prova a inserire l'enum in una struct/namespace e usalo.

+3

Commento a margine: In C++ 0x enumeri sono * tipi di * contesti attraverso i quali è possibile accedere ai valori enumerati. 'enum A {a, b}; A :: a; 'sarà un codice valido, e una volta che è a posto, funzionerà il semplice approccio' using' o 'typedef':' namespace A {enum X {a, b}; } spazio dei nomi B {usando A :: X; } int main() {B :: X x = B :: X :: a; } ' –

1

Se è davvero necessario, provare using namespace foo; anziché using foo::bar;. Tuttavia, è un'idea molto migliore incapsulare l'enum in una classe o in un altro spazio dei nomi.

8

mentre mi piace l'approccio di Marco B migliore, perché non si rompe il codice esistente, è possibile anche effettuare le seguenti operazioni:

 
namespace foo { 
enum bar { 
    A, B [..] 
}; 
} 

namespace buzz { 
using foo::bar; 
using foo::A; 
using foo::B; 
[..] 
} 
1

A partire da C++ 11 è possibile utilizzare enum class . Importazione enum class importa tutti i suoi valori:

namespace foo 
{ 

enum class bar { 
    A 
}; 

} 

namespace buzz 
{ 
using foo::bar; 
} 

int main() 
{ 
    foo::bar f; 
    foo::bar g = foo::bar::A; 

    buzz::bar x; 
    buzz::bar y = buzz::bar::A; 
    buzz::bar z = foo::bar::A; 
} 

il codice viene compilato con successo sopra: http://coliru.stacked-crooked.com/a/2119348acb75d270.

Problemi correlati