5 votes

Accéder aux valeurs des enums en C++98 et C++11

J'ai un ensemble de valeurs d'énumération définies dans la classe "Foo" (ci-dessous).

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

J'utilise une structure pour réduire la portée des valeurs de l'enum Baz et pour montrer qu'il existe un groupe de valeurs liées.

Mon objectif est d'assigner une valeur d'un type enum à une variable. En utilisant la définition de la classe ci-dessus, on peut le faire :

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

Cependant, j'ai l'impression que :

  • A première vue, maValeur semble être initialisé comme un Fii::Foo::Bar mais c'est juste parce que les enum sont un hack pour regrouper des constantes liées dans le parent ( Bar dans ce cas)

Pour améliorer l'état de préparation, j'ai refactorisé le code pour :

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

En utilisant cette nouvelle définition de classe, on peut faire ceci :

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) Pourquoi Fii::Foo::Bar::Baz maValeur = Fii::Foo::Baz::BAZ1 ne fonctionne que sur C++11 ?

Q2) En C++98, existe-t-il un moyen d'écrire Fii::Foo::Baz maValeur = Fii::Foo::Baz::BAZ1 ? Vous êtes autorisé à apporter les modifications que vous souhaitez à la définition de la classe.

Environnement : - Compilateur Clang avec support C++11 - Xcode 4 - Mac OS OS 10.8

7voto

juanchopanza Points 115680

C++11 ajoute classe enums . Il ajoute également une nouvelle façon d'accéder aux valeurs des anciens enums, ce que vous voyez ici.

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)

6voto

Tony D Points 43962

La réponse de juanchopanza est valable pour Q1...

Q2 : En C++98, existe-t-il un moyen d'écrire Fii::Foo::Baz myValue = Fii::Foo::Baz::BAZ1 ? Vous êtes autorisé à faire les changements que vous souhaitez dans la définition de la classe.

Quelque chose comme :

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_;
        };
    };
}

Explication : pour Fii::Foo::Baz::BAZ1 pour être une référence valide à une énumération en C++03, Baz doit être un namespace o class / struct / union . Mais nous essayons de faire croire que Baz lui-même est le type d'énumération, BAZ1 étant l'une des valeurs disponibles. Pour ce faire, nous devons faire de Baz un type défini par l'utilisateur (une classe/structure) capable de stocker toutes les énumérations déclarées dans sa portée. Par conséquent, nous ajoutons un membre de données pour enregistrer la valeur actuelle, un constructeur pour définir la valeur, un opérateur pour exposer la valeur de l'énumération de manière implicite afin que vous n'ayez pas besoin de coder des références explicites à e_ partout dans le code en utilisant Baz ou appeler des get() const función.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X