Есть ли способ сделать 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 для подсказки.
Вы можете попробовать:
enum EEE {
X1 = 1,
XN = -1ULL
};
Без U
целочисленный литерал подписан.
(Это, конечно, предполагает, что ваша реализация поддерживает long long
; я предполагаю, что это так, поскольку в исходном вопросе используется LL
; в противном случае вы можете использовать UL
для a длинный
).
Вы также можете перегрузить операторы, если вы хочу сравнить
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
, и назовите это. Таким образом исчезнут и предупреждения.
Согласно Являются ли перечисления C ++ подписанными или неподписанными? ваш компилятор может выбирать, подписано перечисление или нет, хотя в некоторых комментариях говорится, что в C ++ 0x вы будете может указать, что он беззнаковый.
Отсутствует в текущей версии C ++. C ++ 0x предоставляет строго типизированные перечисления.
В настоящее время вы можете использовать if (static_cast
Почему нет
enum EEE {
X1 = 1,
x = 2 // pick more descriptive name, a'course
};
или
if ( size_t( t ) < x )