In my project I have a lot of enumerations that need to have additional attributes associated with the enumeration members and auxiliary static methods associated with the enumeration type.
As much as I know, this is not possible to have with the standard enum class MyItem {...}, so for each enum class in my project I have an auxiliary class MyItemEnum that encapsulates these auxiliary static methods and also instantiates auxiliary instances of itself, so that I can access their methods in order to get additional attributes.
Bellow an example (simplified as much as possible but I believe all the features to be discussed stayed there).
MyItem.h
enum class MyItem : unsigned int {
Item1 = 1,
Item2 = 5
};
class MyItemEnum {
private:
MyItem myItem;
size_t extInfo;
MyItemEnum(const MyItem& myItem, size_t extInfo);
~MyItemEnum();
public:
static MyItemEnum Item1;
static MyItemEnum Item2;
static const MyItemEnum &get(MyItem myItem);
operator MyItem() const;
size_t getExt() const;
bool hasNext() const;
MyItem next() const;
};
I think the meaning is obvious and I don't need to provide here the .cpp part... I use the MyItem as an argument to be passed in the interfaces and MyItemEnum when I need to access the extended functionality.
My first question is, is the approach above ok, or I should consider something completely different?
My second question concerns an optimization of this enumeration that I am trying to do using constexpr:
enum class MyItem : unsigned int {
Item1 = 1,
Item2 = 5
};
class MyItemEnum {
private:
MyItem myItem;
size_t extInfo;
constexpr MyItemEnum(const MyItem& myItem, size_t extInfo);
public:
static MyItemEnum Item1;
static MyItemEnum Item2;
static constexpr MyItemEnum &get(MyItem myItem);
constexpr operator MyItem();
constexpr size_t getExt();
constexpr bool hasNext();
constexpr MyItem next();
};
It compiles but apparently the constexpr doesn't get chance to get used because if I access:
MyItemEnum::Item1.getExt()
so the compiler doesn't know what values was Item1 instantiated with.
Is there a chance that the expression above will be evaluated as constexpr during the link time optimization?
Alternatively I could use
static constexpr MyItemEnum Item1 = MyItemEnum(MyItem::Item1, 123);
This would active the constexpr compile time optimizations but I am afraid that in some cases, when the constexpr is not possible to be compile-time evaluated, the compiler would have to create a local instance of MyItemEnum (instead of using reference to a single global static instance) and I am afraid that this could lead to a performance penalty (my real enums has more attributes than just a single member so the local instantiation can take some time?). Is this a justified concern?
See Question&Answers more detail:
os