463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122575

C++ What is wrong about using this approach instead of enums when I want a string representation?

There are several questions around concerning this topic (e.g. here and here). I am a bit surprised how lenghty the proposed solutions are. Also, I am a bit lazy and would like to avoid maintaining an extra list of strings for my enums. I came up with the following and I wonder if there is anything fundamentally wrong with my approach...

class WEEKDAY : public std::string{
    public: 
        static const WEEKDAY MONDAY() {return WEEKDAY("MONDAY");}
        static const WEEKDAY TUESDAY(){return WEEKDAY("TUESDAY");}
        /* ... and so on ... */
    private:
        WEEKDAY(std::string s):std::string(s){};
};

Still I have to type the name/string representation more than once, but at least now its all in a single line for each possible value and also in total it does not take much more lines than a plain enum. Using these WEEKDAYS looks almost identical to using enums:

bool isAWorkingDay(WEEKDAY w){
    if (w == WEEKDAY::MONDAY()){return true;}
    /* ... */
    return false;
}

and its straighforward to get the "string representation" (well, in fact it is just a string)

std::cout << WEEKDAY::MONDAY() << std::end;

I am still relatively new to C++ (not in writing but in understanding ;), so maybe there are things that can be done with enums that cannot be done with such kind of constants.

Upvotes: 0

Views: 97

Answers (1)

Mike Seymour
Mike Seymour

Reputation: 254501

You could use the preprocessor to avoid duplicating the names:

#define WEEKDAY_FACTORY(DAY) \
    static const WEEKDAY DAY() {return WEEKDAY(#DAY);}

WEEKDAY_FACTORY(MONDAY)
WEEKDAY_FACTORY(TUESDAY)
// and so on

Whether the deduplication is worth the obfuscation is a matter of taste. It would be more efficient to use an enumeration rather than a class containing a string in most places; I'd probably do that, and only convert to a string when needed. You could use the preprocessor to help with that in a similar way:

char const * to_string(WEEKDAY w) {
    switch (w) {
        #define CASE(DAY) case DAY: return #DAY;
        CASE(MONDAY)
        CASE(TUESDAY)
        // and so on
    }
    return "UNKNOWN";
}

Upvotes: 1

Related Questions