Существует ли способ сделать 'перечислимый' тип, чтобы быть неподписанным?

Есть ли способ сделать enum ввести, чтобы быть неподписанными? Следующий код дает мне предупреждение о сравнении со знаком/неподписанном.

enum EEE {
    X1 = 1
};

int main()
{
    size_t x = 2;
    EEE t = X1;
    if ( t < x ) std::cout << "ok" << std::endl;

    return 0;
}

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

enum EEE {
    X1 = 1,
    XN = 18446744073709551615LL
    // I've tried XN = UINT_MAX (in Visual Studio). Same warning.
};

Но это все еще дает предупреждение.


Изменение, постоянное к UINT_MAX делает его работающий в GNU C++, как должен быть согласно стандарту. Кажется, ошибка в VS. Благодаря James для подсказки.

10
задан Kirill V. Lyadvinsky 28 April 2010 в 18:51
поделиться

5 ответов

Вы можете попробовать:

enum EEE {
    X1 = 1,
    XN = -1ULL
};

Без U целочисленный литерал подписан.

(Это, конечно, предполагает, что ваша реализация поддерживает long long ; я предполагаю, что это так, поскольку в исходном вопросе используется LL ; в противном случае вы можете использовать UL для a длинный ).

8
ответ дан 3 December 2019 в 23:12
поделиться

Вы также можете перегрузить операторы, если вы хочу сравнить

enum EEE {
    X1 = 1
};

bool operator<(EEE e, std::size_t u) {
  return (int)e < (int)u;
}

Однако вы должны танцевать этот танец для любого целочисленного типа с правой стороны. В противном случае, если вы сделаете e <2 , это будет неоднозначно: компилятор может использовать ваш operator <, точно соответствующий левой стороне, но требующий преобразования на правой стороне, или его встроенный оператор, нуждающийся в продвижении для левой стороны и точно совпадающий с правой стороной.

В итоге я бы поставил следующие версии:

/* everything "shorter" than "int" uses either int or unsigned */
bool operator<(EEE e, int u) {
  return (int)e < (int)u;
}

bool operator<(EEE e, unsigned u) {
  return (unsigned int)e < (unsigned int)u;
}


bool operator<(EEE e, long u) {
  return (long)e < (long)u;
}

bool operator<(EEE e, unsigned long u) {
  return (unsigned long)e < (unsigned long)u;
}

/* long long if your compiler has it, too */

Не очень хорошо :) Но, по крайней мере, пользователь вашего перечисления ведет себя спокойно. Однако, если вы в конечном итоге не хотите сравнивать с обычным int , а с некоторым значимым значением, я бы сделал то, что предложил другой парень, и добавил еще один перечислитель, который имеет значение 2 , и назовите это. Таким образом исчезнут и предупреждения.

2
ответ дан 3 December 2019 в 23:12
поделиться

Согласно Являются ли перечисления C ++ подписанными или неподписанными? ваш компилятор может выбирать, подписано перечисление или нет, хотя в некоторых комментариях говорится, что в C ++ 0x вы будете может указать, что он беззнаковый.

1
ответ дан 3 December 2019 в 23:12
поделиться

Отсутствует в текущей версии C ++. C ++ 0x предоставляет строго типизированные перечисления.

В настоящее время вы можете использовать if (static_cast (t) , чтобы удалить предупреждение.

2
ответ дан 3 December 2019 в 23:12
поделиться

Почему нет

enum EEE {
    X1 = 1,
    x = 2 // pick more descriptive name, a'course
};

или

if ( size_t( t ) < x )
0
ответ дан 3 December 2019 в 23:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: