如何使用现代C++来获得与
enum Value_type_id { i, f, d };
union Value { int i; float f; double d; };
struct Item { Value_type_id type; Value value; };
Item add(Item lhs, Item rhs)
{
Item result;
switch (lhs.type)
{
case i:
switch (rhs.type)
{
case i:
result.type = i;
result.value.i = lhs.value.i + rhs.value.i;
break;
case f:
result.type = f;
result.value.f = lhs.value.i + rhs.value.f;
break;
case d:
result.type = d;
result.value.d = lhs.value.i + rhs.value.d;
break;
}
break;
case f:
switch (rhs.type)
{
case i:
result.type = f;
result.value.f = lhs.value.f + rhs.value.i;
break;
case f:
result.type = f;
result.value.f = lhs.value.f + rhs.value.f;
break;
case d:
result.type = d;
result.value.d = lhs.value.f + rhs.value.d;
break;
}
break;
case d:
switch (rhs.type)
{
case i:
result.type = d;
result.value.d = lhs.value.d + rhs.value.i;
break;
case f:
result.type = d;
result.value.d = lhs.value.d + rhs.value.f;
break;
case d:
result.type = d;
result.value.d = lhs.value.d + rhs.value.d;
break;
}
break;
}
return result;
}
字符串
但不必为Item
的两个示例的this和其他函数编写几乎相同的嵌套switch语句,理想情况下,我希望能够执行以下操作:
Item add(Item lhs, Item rhs)
{
return some_magic_here(std::plus{}, lhs, rhs);
}
型
但是我还没有弄清楚如何实现some_magic_here
。基于std::variant
的Item
和基于std::visit
的some_magic_here
乍一看似乎是合适的,直到我发现std::visit
要求返回值对于变量中表示的所有替代项都具有相同的类型。我需要返回类型是两个参数类型中的std::common_type
,这并不总是一样的。
实际上,我的用例有8种不同的数据类型,这导致了64种不同的情况,除了访问联合体的哪些成员之外,这些情况都是相同的。
添加2023-11-11:我的申请(解释型语言的实现)是独立的,(170'000行),并在整个过程中使用枚举/联合/结构。(有很多工作)用别的东西代替它们,但只有在有明显好处的情况下才想这样做,例如,对于不同的支持数据类型,摆脱了许多几乎重复的开关情况。
补充2023-11-15:我现在意识到我也需要一个类似的向量解决方案,但我不知道如何将当前问题的答案扩展到这种情况,所以我在这里提出了一个后续问题:Refactor nested switch statement on union members with vectors, using modern C++
1条答案
按热度按时间8nuwlpux1#
你是正确的,传递给
std::visit
的访问者必须在所有情况下返回相同的类型,但没有理由该类型本身不能是std::variant
:字符串
Example
访问者的返回类型总是
std::variant<int, float, double>
,但是variant
根据lhs
和rhs
中包含的类型而持有不同的类型。