2013-06-13 7 views
9

Ich versuche, einen Alias ​​für eine Enumeration in einem Namespace in einem anderen Namespace einzuführen. Während ich eine Variable vom Alias-Typ deklarieren kann, erkennt der Compiler (gcc 4.1.2) keinen der Werte der Enumeration.C++ typedefs und enums

namespace A 
{ 
    enum a { One = 1, Two = 2 }; 
} 

namespace B 
{ 
    typedef enum A::a b; 
}; 

A::a a_value = A::One; // Pretty standard 
B::b b_value = B::One; // Does not work 
B::b c_value = A::One; // Clearly B is a typedef for A 

int main (int argc, const char *argv[]) 
{ 
    return 0; 
} 

Der Compiler-Fehler ist

test.cc:12: Fehler: 'Eins' ist kein Mitglied von 'B'.

namespace B { 
    typedef A::a b; 
    using A::One; 
} 

Ich glaube nicht, gibt es eine Möglichkeit, sie alle in ohne gesonderte using Aussagen zu bringen:

+0

versuchen Sie mit A :: a als b; in Namespace B (oder so ähnlich). (Das ist, warum dies ein Kommentar ist, und keine Antwort.) – jmucchiello

+4

Das ist, weil 'One' ist ** nicht ** ein Mitglied von' B' ... –

+0

Das ist ein wirklich alter Compiler. Müssen Sie diese Version wirklich verwenden? – stefan

Antwort

7

Während der Aufzählungstyp in B durch b zugänglich ist, werden die Werte nicht und müssen explizit gebracht werden für jeden, es sei denn, Sie tun using namespace A; oder setzen Sie die enum in einen Inline-Namespace und eine using-Anweisung dafür. Letzteres ist möglicherweise vorzuziehen, wenn Sie Bedenken haben, alle A einzubinden, und die Enum-Werte dennoch nur mit A::value verwenden möchten. Hier ein Beispiel:

namespace A 
{ 
    inline namespace en { 
     enum a { One = 1, Two = 2 }; 
    } 

    enum c {Three}; 
} 

namespace B 
{ 
    using namespace A::en; 
    typedef A::a b; 
} 

A::a a_value = A::One; // works; things in en are still visible in A 
B::b b_value = B::One; // works; en was brought into B 
B::b c_value = A::One; // works 
A::c meh = B::Three; //fails; only en was brought into B 

bewusst sein, dass Inline-Namespaces wurde eingeführt in C++ 11, die GCC 4.1.2 für keine Unterstützung hat. Wenn Sie können, würde ich dringend ein Upgrade empfehlen. Die neueste stabile Version ist 4.8.1.

0

C++ vor C++ 11 bietet keine (einfache) Lösung für dieses Problem. In C++ 11, können Sie die Enum scoped, mit der folgenden Syntax deklarieren:

enum struct a { /* .... */ }; // the class keyword may also be used 

Der Effekt ist Enumeratoren (die Konstanten) scoped innerhalb des Aufzählungstypen selbst, dh zu machen. Die Notation, um auf die Konstanten von a zuzugreifen, wird zum Beispiel a::One. Da diese jetzt zum Enum-Typ und nicht zum Namespace gehören, können Sie sie zusammen mit der Enumeration in einen anderen Namespace mit typedef importieren. Beachten Sie jedoch, dass die Werte für die bereichsspezifischen Enum-Werte nicht so einfach wie bei regulären Enums zu int heraufgestuft werden können.

namespace A { 
    enum class a { One = 1, Two = 2 }; 
} 

namespace B { 
    typedef A::a b; 
} 

A::a a_value = A::One; 
B::b b_value = B::One; // Now this works 
B::b c_value = A::One; // Clearly B is still a typedef for A 

int main (int argc, const char *argv[]) { 
    return 0; 
}