DEV Community

Discussion on: Enumérations, ce qui change avec C++11

 
baduit profile image
Lena

J'avoue que je vois mal l'intérêt d'ajouter des méthodes à une énumération, le seul auquel je pense c'est pour faire des conversion en chaine de caractère par exemple et je préfère une simple fonction "to_string(Enum e)".

Si je veux que mes énumérateurs aient de la logique, j'utilise std::variant.

Sinon tu peux quand même tenter une enum dans une classe comme ça godbolt.org/z/5MWrb1We1 , l'opérateur d'assignement ou de comparaisons ne sont pas là par défaut donc faut un peu de code boiler plate, mais avec du CRTP ça devrait simplifier le processus.

Thread Thread
 
pgradot profile image
Pierre Gradot

C'est un contournement possible. Faudrait que j'essaye.

Effectivement, la nécessité de convertir depuis/vers des chaines de caractères est un besoin qui ressort vite.

J'ai aussi des codes où j'ai besoin de catégoriser les valeurs de l'énumération. Genre :

    enum Colors {
        GREEN_LIGHT, GREEN_DARK, RED_DARK

        bool isDark() const {
            return ....;
        }
    };

    auto c = Colors::GREEN_DARK;
    c.isDark();
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
baduit profile image
Lena • Edited

Ouai je vois du coup.
Vu que j'aime pinailler tu pourrais aussi faire comme ça :

struct Color
{
    enum class Bases
    {
        GREEN,
        RED
    };

    enum class Modifiers
    {
        LIGHT,
        DARK
    };

    Bases base;
    Modifiers modifier;

    bool isDark() const { return modifier == Modifiers::DARK; }
};

auto c { colors::Bases::GREEN, colors::Modifiers::DARK };

// Why not add a user defined literal for the fun
consteval Color operator""_color(const char*, std::size_t)
{
    // ...
}

auto c = "GREEN DARK"_color;
Enter fullscreen mode Exit fullscreen mode

En vrai tu perds l'auto-complétions ou bien c'est beaucoup plus verbeux. En plus le code est plus complexe, je pense pas que ça une meilleur solution.

Thread Thread
 
pgradot profile image
Pierre Gradot

L'exemple était un peu particulier et effectivement, une technique comme celle-ci serait plus intéressante.

Dans un code actuel, j'ai utilisé un namespace pour le nom de l'énumération, une enum class ID et des fonctions libres dans le namespace. Mais je ne suis pas satisfait à 100%. En reprenant l'exemple ci-dessus :

namespace Colors {

enum class ID {
    GREEN_LIGHT, GREEN_DARK, RED_DARK
};

bool isDark(ID color) {
    return color == ID::GREEN_DARK or color == ID::RED_DARK;
}

}

int main() {
    auto c = Colors::ID::GREEN_DARK;
    Colors::isDark(c);
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
baduit profile image
Lena

Ca reprends l'idée de la surcharge de l'opérateur ->* dont j'ai parlé précédemment, mais j'avais fait ça il y a quelque temps qui pourrait peut être faire ce que tu veux dans ton cas github.com/Baduit/Unic . Ca reprends l'idée de l'Uniform function call syntax qui existe dans d'autres langage (et il y a aussi des propositions d'intégration en C++ mais aucune n'a aboutit il me semble)