Могу ли я иметь перечисление с немаркированными значениями в C ++? - PullRequest
0 голосов
/ 17 мая 2011

В основном я хочу ограничить переменные значениями 0, 1 или 2.

Я попытался сделать это со следующим:

enum Value
{
    0,
    1,
    2
};
Value var;

Но это ошибка компиляции, потому чтоПеречисляемые значения не имеют маркировки.Это просто делает код менее читабельным для присвоения имен, таких как "ZERO", "ONE" и "TWO", а не для ссылки на значения как 0, 1 и 2. Есть ли способ обойти это или я должен просто избавиться от enumи применять правило в другом месте?

Ответы [ 3 ]

1 голос
/ 17 мая 2011

То, что вы добавляете идентификаторы для значений, не означает, что вы должны их использовать ... вы можете использовать Value(0), Value(2) и т. Д., Если это более удобно, но есть опасность: enum нене ограничивайте сохраненные значения перечисленными ... например, он не защитит вас от Value(3).

Внутри структур / классов вы можете использовать битовые поля, чтобы ограничить хранилище, используемое для чисел, но даже тогда: - диапазон должен соответствовать возможным значениям со знаком или без знака в количестве запрошенных битов - попытки присвоить другие значения приведут к удалению старших битов, а не к какой-либо ошибке времени компиляции или выполнения

Если вы намереваетесь создать отдельный тип, который применяет ограниченные значения от 0 до 2, то вам нужен класс со специализированным конструктором и операторами присваивания:

template <int MIN, int MAX>
class Bound
{
  public:
    explicit Bound(int n) { *this = n; }

    Bound& operator=(int n)
    {
        if (n < MIN or n > MAX)
            throw std::runtime_error("out of bounds");
        n_ = n;
        return *this;
    }
    Bound& operator+=(int n) { *this = n_ + n; }

    // should "+" return int or Bound?  entirely usage dependent...
    Bound operator+(int n) { return Bound(n_ + n); }

    // -=, -, *=, *, /=, /, %=, %, bitwise ops, pre/post ++/-- etc...

    operator int() const { return n_; }

  private:
    int n_;
};
1 голос
/ 17 мая 2011

Если вы хотите использовать enum, то вам нужно назвать их. Поскольку вы просто работаете с целочисленными значениями и, по-видимому, хотите, чтобы они действительно представляли целочисленные значения, лучше всего использовать параметр int и выполнить быструю проверку в верхней части метода. Будет приветствоваться комментарий к методу, определяющему это ограничение.

Обратите внимание, что если ваши значения на самом деле соответствуют нечисловым настройкам, вам просто нужно придумать хорошие имена и использовать enum

0 голосов
/ 17 мая 2011

Вы ищете встроенный int тип, AFAICT

Если вы действительно хотите вести себя как программист на Java использовать ADT в религиозном отношении, вы всегда можете:

template <typename ordinal=int>
struct Value
{
    ordinal _val;
    /*implicit*/ Value(ordinal val) : _val(val) {}
    /*implicit*/ operator const ordinal&() const { return _val; }
    /*implicit*/ operator       ordinal&()       { return _val; }
};

int main()
{
    Value<> x = 3;
    int y = x;
    x = y;

    x += 17;
    x++;

    return x;
}

Это вернет 22 * ​​1011 *

Конечно, вполне возможно сделать Value <> менее универсальным и более полезным во многих отношениях, но вы на самом деле ничего не сказали нам о том, что вы хотите с этим

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...