gpt4 book ai didi

c++ - 访问结构的 union 成员的优雅方式

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:42:03 25 4
gpt4 key购买 nike

有没有办法反转#define指令?

在下面的例子中

#define ZERO 0
#define ONE 1
#define TWO 2
#define THREE 3

是否可以从整数值 2 中检索出 TWO?

此示例来自 C 代码,但如果需要,我可以使用一些 C++ 代码。我的目标是能够分解一些这种形式的虚假 switch-case 循环:

switch(num)
{
case ZERO:
return std::to_string(foo.V_ZERO);
case ONE:
return std::to_string(foo.V_ONE);
case TWO:
return std::to_string(foo.V_TWO);
case THREE:
return std::to_string(foo.V_THREE);
}

其中 foo 是这样一个结构的实例:

struct Foo
{
union Val
{
int V_ZERO;
int V_ONE;
double V_TWO; // nonsense: just to say that types are not the same
int V_THREE;
};
};

我的约束如下:

  1. 我不能删除#define 提供的功能,即我可以写一些等效的东西,例如枚举,但我不能丢失 ZERO 和 0、ONE 和 1 等之间的映射;
  2. 现有代码是用 C 编写的,我无法用 C++ 重写它。但是,我可以编写一些补充 C++ 代码。

我有一些简化代码的想法,但我想知道是否有一种众所周知的优雅方法可以做到这一点,尤其是通过某些模板或预处理器指令。

编辑:添加 std::to_string 的用法是说我对了解如何从 union 转换或处理多种类型不感兴趣。

最佳答案

如果您想自动化某些过程,一种选择是使用 xmacros。它们是 hacky,但根据您的代码大小可能会使维护(如添加新条目)更容易,但代价是您同事的愤怒:

定义 xmacro 列表:

#define XLIST(xmacro) \
xmacro(ZERO, 0) \
xmacro(ONE, 1) \
xmacro(TWO, 2) \
xmacro(THREE, 3) \

然后在您想遍历所有项目时使用它:

// create an enum containing all items
#define xmacro(name, value) name,
enum Item
{
XLIST(xmacro)
};
#undef xmacro

// get the number of items
#define xmacro(name, value) +1
const int NumberOfItems = 0 XLIST(xmacro);
#undef xmacro

// enum -> value
int itemToValue(enum Item item)
{
switch (item)
{
// create a mapping from enum to x
#define xmacro(name, value) case name: return value;
XLIST(xmacro)
#undef xmacro
}

return -1;
}

// get enum name
const char * getItemName(enum Item item)
{
switch (item)
{
// create a mapping from enum to x
#define xmacro(name, value) case name: return #name;
XLIST(xmacro)
#undef xmacro
}

return NULL;
}

这将被预处理成如下内容:

enum Item
{
ZERO,
ONE,
TWO,
THREE,
};

const int NumberOfItems = 0 +1 +1 +1 +1; // == 4

int itemToValue(enum Item item)
{
switch (item)
{
case ZERO: return 0;
case ONE: return 1;
case TWO: return 2;
case THREE: return 3;
}

return -1;
}

const char * getItemName(enum Item item)
{
switch (item)
{
case ZERO: return "ZERO";
case ONE: return "ONE";
case TWO: return "TWO";
case THREE: return "THREE";

}

return NULL;
}

您可以从中创建您想要的任何映射,即对于您的结构,您可以使用类似于@Jean-François 所写的东西:

// get struct value by item type
double getValueByName(enum Item item, struct Foo values)
{
switch (item)
{
// create a mapping from enum to x
#define xmacro(name, value) case name: return values.V_##name;
XLIST(xmacro)
#undef xmacro
}

return -1;
}

关于c++ - 访问结构的 union 成员的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48944820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com