#c #enums
#c #перечисления
Вопрос:
У меня есть класс enum, определенный таким образом в MyClass.h:
enum class SpeedMode {
SPEED_SLOW = 0,
SPEED_NORMAL = 1,
SPEED_FAST = 2
};
В другом файле я хотел бы использовать свое перечисление в качестве int:
void myOtherClass::myFunc(const SpeedModeamp; speed_mode) {
int speed_as_int = speed_mode;
.
.
.
}
В том же файле, в котором я определил свое перечисление (MyClass.h), я пытаюсь определить переопределение оператора:
int operator= (const SpeedModeamp; mode) {
return static_cast<int>(mode); //The real logic is more complex and will use a switch statement
}
Но я получаю эту ошибку: error: 'int operator=(const SpeedModeamp;)' must be a nonstatic member function
.
Если я попытаюсь обернуть его во что-то подобное struct SpeedModeUtils { }
, что позволяет этому файлу компилироваться, но затем MyOtherClass выдает мне эту ошибку, когда я пытаюсь использовать переопределение: error: cannot convert 'const SpeedMode' to 'int' in initialization
Я знаю, что мог бы использовать старое неклассовое перечисление, но это большой проект, и я предпочитаю безопасность типов класса enum. Я также знаю, что могу использовать static_cast, но я бы предпочел избежать этого по очевидным причинам.
Если это не удастся, я просто использую функцию преобразования вручную, но решил, что это будет «более приятный» способ справиться с этим.
Комментарии:
1. Что такое
SpeedMode
? вызывается перечисление, котороеSpeed
не показало никакой структуры.SpeedMode
2. Кроме того, у меня есть еще один. 1) Почему вы используете
enum class
, а не простоenum
? Если вы используете более позднее перечисление, оно будет просто целочисленным представлением, и вы можете сказатьint convertSpeedToInt(Speed mode) {return mode;}
3. Я надеюсь обеспечить безопасность типов в классе enum, хотя да, я думаю, что остановлюсь на простой вспомогательной функции, содержащей оператор switch .
4. На всякий случай, что вы имеете в виду под безопасностью типов, так это то, что вы можете избежать сравнения с другими перечислениями и целыми числами, верно?
5. Да, это в основном описывает это. Также, чтобы избежать столкновения имен, принудительно используя SpeedMode::SPEED_SLOW вместо простого использования SPEED_SLOW.
Ответ №1:
Вам нужен доступ к базовому типу данных класса enum, то есть к int . Способ сделать это — использовать std::underlying_type<T>
для доступа к целочисленному значению. Способ, которым вы это делаете,:
#include <type_traits>
auto speed_mode_as_int = static_cast<std::_underlying_type<SpeedMode>::type>(speed_mode);
Я привел здесь минимальный рабочий пример, который должен помочь вам начать
#include <type_traits>
#include <iostream>
#include <cassert>
enum class SpeedMode {
SPEED_SLOW = 0,
SPEED_NORMAL = 1,
SPEED_FAST = 2
};
bool is_fast(const SpeedModeamp; speed_mode)
{
auto speed_mode_as_int =
static_cast<std::underlying_type<SpeedMode>::type>(speed_mode);
switch(speed_mode_as_int)
{
case 2:
return true;
default:
return false;
}
}
int main(void) {
auto mode = SpeedMode::SPEED_SLOW;
assert(false == is_fast(mode));
mode = SpeedMode::SPEED_NORMAL;
assert(false == is_fast(mode));
mode = SpeedMode::SPEED_FAST;
assert(true == is_fast(mode));
return 0;
}
Я скомпилировал его со следующей строкой компиляции: clang -std=c 17 main.cpp
.
Комментарии:
1. Спасибо, по сути, это то, что я закончил делать вчера. Не совсем так чисто, как я надеялся, но это хороший ответ.
Ответ №2:
Как сказал вам компилятор, вы не можете определить такой оператор присваивания. Он сказал int operator=(const SpeedModeamp;)' must be a nonstatic member function
, что перечисления просто не имеют членов в C .
Комментарии:
1. Да, я понял эту часть, поэтому я попытался обернуть ее в структуру Util, но как мне сделать ее доступной для всего мира? (Или, по крайней мере, везде, где включен файл MyClass.h)
2. Не могли бы вы быть более понятными? Я понял, что вы еще не успешно внедрили Util struct , так что вы хотите сделать «глобально доступным»?
3. Как можно проще и понятнее спросить: как мне импортировать operator= override, чтобы он использовался в MyOtherClass ?
4. @Fozefy Ты этого не делаешь. Это просто невозможно.