假设我有一个像这样的强类型枚举类型:
enum class message : int {
JOIN = 0,
LEAVE = 4,
SPAWN = 1,
}
Run Code Online (Sandbox Code Playgroud)
我需要安全地(在这种情况下,安全地意味着丢弃无效的变体)将其从其基础类型(int)进行转换。
为此,我有一个函数可以将其转换为我:
std::optional<message> get_message(int num) {
return num == (int)message::JOIN || num == (int)message::LEAVE || num == (int)message::SPAWN ? (message)num : {};
}
Run Code Online (Sandbox Code Playgroud)
这是可行的,但是编写起来很长并且容易出错,尤其是对于具有大量变体的枚举。
有没有办法在C ++ 17中自动执行此过程?
有许多方法可以迭代连续的枚举
enum Animal {Cat, Dog, Dolphin}
Run Code Online (Sandbox Code Playgroud)
但有没有一种方便简单的方法来迭代非连续的枚举元素
enum Animal {Cat = 0, Dog = 5, Dolphin = 8}
Run Code Online (Sandbox Code Playgroud) 我可能想要实现不可能的,但StackExchange总是让我感到惊讶,所以请你去看看:
我需要将名称映射到整数.名字(约2k)是独一无二的.该列表不会有任何添加或删除,并且这些值在运行时不会更改.
将它们作为const int变量实现,可以对存在和类型进行编译时检查.这在代码中也非常清晰和冗长.很容易发现错误.
实现它们为std::map<std::string, int>我提供了很大的灵活性来构建名称以查找字符串操作.我可以使用它来将字符串作为参数提供给函数,这些函数可以通过在该字符串后附加前缀/后缀来查询列表中的多个值.我还可以通过从循环变量创建键名的数字部分来循环遍历多个值.
现在我的问题是:是否有一种结合两种优势的方法?缺少编译时检查(特别是对于密钥存在)几乎杀死了我的第二种方法.(特别是如果密钥不存在,则会std::map无声地返回0,这会导致很难找到错误.)但循环和前/后缀添加功能非常有用.
我更喜欢不使用任何其他库(如boost)的解决方案,但请尽可能地建议它们,因为我可能无论如何都可以重新实现它们.
关于我对地图做什么的一个例子:
void init(std::map<std::string, int> &labels)
{
labels.insert(std::make_pair("Bob1" , 45 ));
labels.insert(std::make_pair("Bob2" , 8758 ));
labels.insert(std::make_pair("Bob3" , 436 ));
labels.insert(std::make_pair("Alice_first" , 9224 ));
labels.insert(std::make_pair("Alice_last" , 3510 ));
}
int main()
{
std::map<std::string, int> labels;
init(labels);
for (int i=1; i<=3; i++)
{
std::stringstream key;
key << "Bob" << i;
doSomething(labels[key.str()]);
}
checkName("Alice");
}
void checkName(std::string name)
{
std::stringstream key1,key2;
key1 << name << "_first";
key2 << …Run Code Online (Sandbox Code Playgroud) 我得到了枚举
enum ProgramID
{
A = 0,
B = 1,
C = 2,
MIN_PROGRAM_ID = A,
MAX_PROGRAM_ID = C,
} CurrentProgram;
Run Code Online (Sandbox Code Playgroud)
现在,我试图CurrentProgram像这样增加:CurrentProgram++,但编译器抱怨:no 'operator++(int)' declared for postfix '++' [-fpermissive].我认为有这样一个运算符增加"枚举",但如果没有,我如何获得其中一个值的后继?
我有类的风格Class1(见代码).枚举和函数从枚举中获取所有值.值(FOO_1,FOO_2等)从类到类别以及值(数量不同sizeof(Foos)).我调用该函数一次拿到的sizeof枚举,备用内存和与第二呼叫我想所有的值*pFoos(2,1,6在示例代码中).有没有更好的方法然后使用包含所有值的数组(size_t arr[3] ={FOO_1 , FOO_X, FOO_BAR })?
class Class1{
enum Foos{
FOO_1 = 2,
FOO_X = 1,
FOO_BAR = 6
}
};
Class1::GetFoos(size_t* pFoos, size_t* pSize)
{
size_t len = sizeof(Foos);
if (len > *pSize)
{ //Call function once to get the size
*pSize= len ;
return -1;
}
for(size_t i = 0; i< *pSize; i++)
{
//copy all enum values to …Run Code Online (Sandbox Code Playgroud) 对于嵌入式项目中的 UI,我正在寻找一种很好的通用方式来存储“状态”并通过按下按钮(例如菜单项列表)循环浏览它。
通常,我喜欢为此目的使用枚举,例如:
enum class MenuItem {
main,
config,
foo,
bar,
};
Run Code Online (Sandbox Code Playgroud)
然后,在我的 UI 代码中,我可以存储一个currentMenuItem状态,如
MenuItem currentMenuItem = MenuItem::MAIN;
Run Code Online (Sandbox Code Playgroud)
并通过与currentMenuItem枚举中声明的任何可能值进行比较来根据当前状态执行操作。
问题是,我现在想进入下一个菜单项。为此,我可以非常轻松地编写一个函数,通过强制转换为 int,递增 1,然后将其转换回枚举来执行此操作。我有多个不同的枚举,所以我什至可以使用这个模板化函数来为任意枚举执行此操作:
template <typename T>
void advanceEnum(T &e) {
e = static_cast<T>(static_cast<int>(e) + 1);
}
Run Code Online (Sandbox Code Playgroud)
这样做的问题是它不会环绕:它会很高兴地继续增加底层整数,使其超出实际枚举中的元素数量。我可以很容易地解决这个问题(通过对上述函数中的元素数取模),只要有一种干净的方法来获取枚举的元素数。其中,据我所知,真的没有。
我正在考虑编写一个实现此行为的自定义“CyclicEnum”类,我随后可以从中派生。这样,我也可以把它写成一个重载的operator++.
但是,我仍然没有设计出如何在不实际使用枚举的情况下获得类似枚举的东西。例如,我得到了这样的东西:
class CyclicEnum {
public:
uint8_t v;
CyclicEnum& operator++() {
v = (v+1) % count;
return *this;
}
CyclicEnum operator++(int) {
CyclicEnum old = *this;
operator++();
return old;
}
private:
uint8_t count;
protected: …Run Code Online (Sandbox Code Playgroud) 不幸的是,我发现迭代常规 s 的所有标准技术enum都不适用于enum classes,因为枚举类不会隐式转换为整数。
不是如何迭代枚举?,因为我询问的是 an enum class(即:强类型枚举),而他们询问的是常规enum(即:弱类型枚举)。
是否可以循环并提取枚举中每个项目的值,例如:
enum {
item 1 = 1,
item 2 = 7,
item 3 = 'B'
} items;
Run Code Online (Sandbox Code Playgroud)
要说一个阵列.可能?
你好,我有以下枚举
enum params_Solver {
params_Solver_Lorem,
params_Solver_Ipsum,
params_Solver_Simply,
params_Solver_Dummy,
params_Solver_Test,
params_Solver_Typesetting,
params_Solver_Industry,
params_Solver_Scrambled
};
Run Code Online (Sandbox Code Playgroud)
我想要做的是尝试做这样的伪代码:
for (auto enum_member: params_Solver)
{
print(index, enum_member); // output looks like this: "0, params_Solver_Lorem", "1, params_Solver_Ipsum" etc
}
Run Code Online (Sandbox Code Playgroud)
有没有办法实现这一目标?
编辑:我无法控制枚举。此枚举由来自第 3 部分库的不同文件提供。我可能可以复制它但不能更改原始枚举。我想将枚举库的成员写入不同的文件。
我在尝试为C++中的每个循环制作时遇到问题.我不确定这是否可能在C++中如果我仍然不知道这样做.
我有一个简单的问题用帕斯卡写的,它找到了一年中的一天,当时是星期五13或星期六25没有遇到哪一天.
在pascal我有这样的代码:
{First I declare types}
type
months = (January, February, March, April, May, June, July, August, September, October, November, December);
...
{Then I declare variable for months}
var
m: mesec;
...
{Then I can declare for loop that will loop over months}
for m:= januar to december do
...
Run Code Online (Sandbox Code Playgroud)
在python中也可以使用类似的方法为每个循环执行枚举.我的问题是:
在C++中有没有任何方法可以为枚举做甚至循环?
我知道这可能看起来像一个乞讨者的问题,但我尝试了几种不同的方法来做它不起作用.不编译.
我在谷歌上搜索如何迭代枚举,发现了各种建议,例如 如何迭代枚举? 尽管所有这些方法都必须导致迭代整数,但我发现建议的解决方案或多或少是一种黑客行为。是否有更深层的原因导致此操作没有得到更好的支持;或者从另一方面来看,哪个更可移植(包括C和C++之间的一个)并且更符合标准?
C++ 枚举问题。
所以我有一个文件列表及其 ID,我需要对其进行迭代并执行操作。大多数内容是相同的,但有一些特定于文件的事情需要完成。我尝试将文件 ID 放入枚举中,然后对其进行迭代。然而,文件 ID 是不连续的,并且会跳跃。
目前,我有类似的东西
for(int i = 0; i < FILE_ENUM_MAX; i++)
{
currentFile = myEnum(i);
// do stuff
}
enum myEnum {
file1 = 0x1111,
file2 = 0x8000,
file3 = 0x75,
file4 = 0x120,
FILE_ENUM_MAX = 4
}
Run Code Online (Sandbox Code Playgroud)
这是行不通的;我只是浏览文件 0、1、2 和 3。我的想法是,我不能通过询问项目 N 来获取枚举中的第 N 个项目。那么迭代此枚举的最佳方法是什么?或者我应该摆脱它?我可能可以按数字顺序排列项目,但我更喜欢顺序无关紧要的解决方案。