2012-09-12 17 views
5

Ho un insieme di valori enum definiti nella classe "Foo" (sotto).Valori di enum di accesso in C++ 98 e C++ 11

namespace Fii 
{ 
    class Foo 
    { 
     struct Bar 
     { 
      enum Baz 
      { 
       BAZ1, 
       BAZ2, 
       BAZ3 
      }; 
     }; 
    }; 
}; 

Sto usando una struct per ridurre l'ambito di valori enum Baz così come dimostrano ci sono un gruppo di valori correlati.

Il mio obiettivo è assegnare un valore da un tipo di enum a una variabile. Utilizzando la definizione della classe di cui sopra, si può fare questo:

Fii::Foo::Bar::Baz myValue = Fii::Foo::Bar::BAZ1 (Works in both C++98 and C++11) 

Tuttavia, ritengo che:

  • A prima vista, myValue sembra essere inizializzato come Fii :: :: Foo Bar ma questo è solo perché enum sono un trucco per le costanti correlate del Gruppo nel genitore (Bar in questo caso)

per migliorare la prontezza, II ri-scomposto il codice per:

namespace Fii 
{ 
    class Foo 
    { 
     enum Baz 
     { 
      BAZ1, 
      BAZ2, 
      BAZ3 
     }; 
    }; 
}; 

Utilizzando questa nuova definizione di classe, si può fare questo:

Fii::Foo::Baz myValue = Fii::Foo::Baz::BAZ1 (Works in C++11 only) 
Fii::Foo::Baz myValue = Fii::Foo::BAZ1 (Should work on C++98 and C++11 - not tested) 

Q1) Perché è Fii :: Pippo :: Pluto: : Baz myValue = Fii :: Foo :: Baz :: BAZ1 funziona solo su C++ 11?

Q2) In C++ 98, c'è un modo per scrivere Fii :: Foo :: Baz myValue = Fii :: Foo :: Baz :: BAZ1? Puoi apportare le modifiche che ti piacciono nella definizione della classe.

Ambiente: - compilatore Clang con C++ 11 supporto - Xcode 4 - Mac OS OS 10.8

risposta

5

di juanchopanza valida per il Q1 ...

Q2: In C++ 98, c'è un modo di scrivere Fii :: Foo :: Baz myValue = Fii :: :: Foo Baz :: BAZ1? Puoi apportare le modifiche che ti piacciono nella definizione della classe.

Qualcosa di simile:

namespace Fii 
{ 
    class Foo 
    { 
     class Baz 
     { 
      public: 
      enum E { BAZ1, BAZ2, BAZ3 }; 
      Baz(E e) : e_(e) { } 
      operator const E() const { return e_; } 
      private: 
      E e_; 
     }; 
    }; 
} 

Spiegazione: per Fii::Foo::Baz::BAZ1 per essere un riferimento valido ad un'enumerazione in C++ 03, Bazdeve essere unnamespace o class/struct/union. Ma stiamo cercando di far sembrare che Baz sia il tipo di enumerazione, con BAZ1 che è uno dei valori disponibili. Per fare ciò, dobbiamo rendere Baz un tipo definito dall'utente (una classe/struct) in grado di memorizzare una qualsiasi delle enumerazioni dichiarate nel suo ambito.Pertanto, aggiungiamo un membro dati per registrare il valore corrente, un costruttore per impostare il valore, un operatore per esporre il valore di enumerazione implicitamente in modo da non dover codificare riferimenti espliciti a Baz oggetti o Baz oggetti nel codice. chiamare la funzione get() const.

+0

Puoi spiegare perché è necessario questo codice? Baz (E e): e_ (e) {} operatore const E() const {return e_; } private: E e_; –

+0

@DavidAndreoletti: nel codice sopra, Baz è un "tipo definito dall'utente" - una classe le cui istanze di oggetto gestiscono ciascuna un singolo valore 'E'. Il codice richiesto è il costruttore che memorizza una delle enumerazioni, un operatore che fornisce implicitamente un valore 'E' ogni volta che l'oggetto appare in un'espressione in cui il compilatore non sa cosa fare con un' Baz', e il variabile membro che memorizza 'E'. È chiaro? - sentiti libero di chiedere ulteriori chiarimenti/esempi .... –

+0

Ho provato il tuo suggerimento e funziona bene. Pensi che questa leggibilità del codice di aiuto e non ostacoli la manutenibilità del codice? –

6

C++ 11 aggiunge class enums. Aggiunge anche un nuovo modo di accedere ai valori enum vecchio stile, che è quello che stai vedendo qui. di risposta

enum Foo { FOO1, FOO2, FOO3 }; // old-style enum 

Foo f1 = Foo::FOO1; // OK in C++11, error in C++98. 
Foo f2 = FOO1; // OK in C++98 and C++11 (for backward compatibility)