Каков наилучший способ для несеквенциального целого числа С++ enums

Следуя шаблону перечисления С++, который я уже здесь описал, я пытался сделать подобное, но на этот раз последовательность значений, которые я хочу использовать, не понятна непрерывные целые числа.

Код явно ошибочен:

class Rotations
{
    enum PossibleIndexes
    {
        ZERO,
        PLUS180,
        PLUS90,
        MINUS90
    };


    enum PossibleValues
    {
        ZERO= 0,
        PLUS180= 180,
        PLUS90= 90,
        MINUS90= -90
    };

    static int Count() { return MINUS90 + 1; }

    static PossibleValues Default(){ return ZERO; }
};

так как будут конфликты между элементами, присущими двум перечислениям.

Итак, мой вопрос: каков наилучший подход к реализации фиксированного количества жестко закодированных ротаций {0, 180, 90, -90}, который также имеет функциональность по умолчанию и счетчик?

Ответ 1

Из-за ограничений Visual С++ 2010 Compilation Toolkit (не полностью совместимый с С++ 11) мне пришлось отказаться от более низких подходов.

Сообщение в fooobar.com/questions/9969/... также предложило мне интересный подход для получения значений.

class Rotations
{
public:
    typedef enum
    {
        ZERO= 0,
        PLUS180= 180,
        PLUS90 = 90,
        MINUS90 = -90
    }PossibleValues;

    static const PossibleValues PossibleValuesCollection(int index) {
        static const PossibleValues values[] = { ZERO, PLUS180, PLUS90, MINUS90 };

        return values[index];
    }

    static int Count() { return 4; }
    static PossibleValues Default(){ return ZERO; }
};

Ответ 2

Вы всегда можете сохранить статический std:: initializer_list, содержащий все возможные значения

namespace PossibleValues
{
    enum Type
    {
        ZERO= 0,
        PLUS180= 180,
        PLUS90= 90,
        MINUS90= -90
    };

    constexpr auto Values = {ZERO, PLUS180, PLUS90, MINUS90};
    size_t Count() { return Values.size(); }
    Type Default() { return *begin(Values); }
}

Этот подход будет иметь дополнительный бонус, позволяющий выполнять итерацию значений перечисления в цикле

Примечание. Я хочу, чтобы компилятор мог сгенерировать весь этот код, хотя, по крайней мере, для класса enum

Ответ 3

Отказ от ответственности: я упоминаю недавно опубликованную библиотеку с открытым исходным кодом.

Возможно, вы захотите посмотреть Улучшенные перечисления. Это избавит вас от необходимости повторять что-либо.

#include <enum.h>
ENUM(Rotations, int, ZERO = 0, PLUS180 = 180, PLUS90 = 90, MINUS90 = -90)

Затем вы можете получить доступ к числу констант как

Rotations::_size

В настоящее время нет встроенного способа объявления значения по умолчанию. Однако конструктор по умолчанию в настоящее время является закрытым, поэтому вам нужно будет указать значение при создании значения Rotations. Существует синтаксически "хороший" способ сделать это показано здесь - посмотрите, как недопустимый определяется с помощью шаблона. Это может быть полный избыток для ваших нужд. Если вы попробуете эту библиотеку и получите отзывы о значениях по умолчанию, сообщите мне.

Я должен отметить, что значение count и default генерируются во время компиляции.