问题描述
我对C ++还是比较陌生,因此尝试寻找在一个实体下存储不同类型值的最佳方法。 上下文是,我有一个返回结构的函数,值之一可以是不同的类型。在任何时候,只会设置一个值。 对我来说,最好的情况是我可以做这样的事情:
Union Union1 {
int x;
char y;
double z;
}
executor(Union1 union1) {
if(union1.x.isSet()) {
doSomethingUsingX();
} else if(union1.y.isSet()) {
doSomethingElseUsingY();
}
}
我不认为这是可能的,因为c ++联合使用相同的内存空间。 那有什么我可以用的吗?
解决方法
如果您使用的是C ++ 17或更高版本,请尝试std::variant
。参见https://en.cppreference.com/w/cpp/utility/variant
如果早于C ++ 17,则可以尝试boost::variant
variant
是进行联合的更好方法。它还记录了其中存储了什么东西,您可以使用std::visit
在variant
上调用类型重载函数。
就像这样,根据cppreference示例改编而成:
#include <iostream>
#include <variant>
#include <vector>
// helper type for the visitor #4
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
// explicit deduction guide (not needed as of C++20)
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
int main() {
std::vector<std::variant<int,char,double>> v;
v.emplace_back(1);
v.emplace_back('c');
v.emplace_back(2.7);
for (const auto &x : v) {
std::visit(
overloaded{[](auto arg) { std::cout << "unknown " << arg << '\n'; },[](int arg) { std::cout << "int " << arg << '\n'; },[](double arg) { std::cout << "double " << arg << '\n'; },[](char arg) { std::cout << "char " << arg << '\n'; }},x);
}
return 0;
}
我在网上发现的这篇博客文章似乎也有助于解释其工作原理: https://pabloariasal.github.io/2018/06/26/std-variant/
,您可以使用枚举来报告返回类型:
typedef enum
{
x,y,z
}returnType;
typedef struct
{
returnType rt;
union
{
int x;
char y;
double z;
};
}myStruct;
//...
myStruct AFunctionWithMyStructReturnType(int arg)
{
myStruct ms;
if(arg == 0)
{
ms.rt = returnType.x;
ms.val = 10000;
}
else if(arg == 1)
{
ms.rt = returnType.y;
ms.val = 200;
}
else
{
ms.rt = returnType.z;
ms.val = 3.14;
}
return ms;
}
//...
myStruct S = AFunctionWithMyStructReturnType(arg);
switch(S.rt)
{
case returnType.x:
processX(S.val);
break;
case returnType.y:
processY(S.val);
break;
case returnType.z:
processZ(S.val);
break;
}