В моем проекте у меня много перечислений, которым необходимо иметь дополнительные атрибуты, связанные с членами перечисления, и вспомогательные статические методы, связанные с типом перечисления.
Насколько мне известно, это невозможно сделать со стандартным классом перечисления MyItem {...}, поэтому для каждого класса перечисления в моем проекте у меня есть вспомогательный класс MyItemEnum, который инкапсулирует эти вспомогательные статические методы, а также создает экземпляры вспомогательных экземпляров сам, чтобы я мог получить доступ к их методам для получения дополнительных атрибутов.
Ниже приведен пример (максимально упрощенный, но я считаю, что все обсуждаемые функции остались там).
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;
};
Я думаю, что смысл очевиден, и мне не нужно указывать здесь часть .cpp ... Я использую MyItem в качестве аргумента для передачи в интерфейсах и MyItemEnum, когда мне нужно получить доступ к расширенным функциям.
Мой первый вопрос: подходит ли описанный выше подход или мне следует рассмотреть что-то совершенно другое?
Мой второй вопрос касается оптимизации этого перечисления, которое я пытаюсь выполнить с помощью 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();
};
Он компилируется, но, по-видимому, constexpr не может быть использован, потому что если я получу доступ:
MyItemEnum::Item1.getExt()
поэтому компилятор не знает, с какими значениями был создан экземпляр Item1. Есть ли вероятность, что приведенное выше выражение будет оценено как constexpr во время оптимизации времени ссылки? В качестве альтернативы я мог бы использовать
static constexpr MyItemEnum Item1 = MyItemEnum(MyItem::Item1, 123);
Это активировало бы оптимизацию времени компиляции constexpr, но я боюсь, что в некоторых случаях когда constexpr невозможно оценить во время компиляции, компилятор должен будет создать локальный экземпляр MyItemEnum (вместо этого использования ссылки на один глобальный статический экземпляр), и я боюсь, что это может привести к снижению производительности (мои настоящие перечисления имеют больше атрибутов, чем просто один член, поэтому создание локального экземпляра может занять некоторое время?). Это обоснованное беспокойство?