我正在创建一个类,该类存储有关特定数据源的元数据。元数据是在树中构造的,与XML的构造非常相似。元数据值可以是整数,十进制或字符串值。
我很好奇C ++中是否有一种很好的方法来存储这种情况下的变体数据。我希望该变体使用标准库,因此避免使用可用的COM,Ole和SQL VARIANT类型。
我当前的解决方案如下所示:
enum MetaValueType
{
MetaChar,
MetaString,
MetaShort,
MetaInt,
MetaFloat,
MetaDouble
};
union MetaUnion
{
char cValue;
short sValue;
int iValue;
float fValue;
double dValue;
};
class MetaValue
{
...
private:
MetaValueType ValueType;
std::string StringValue;
MetaUnion VariantValue;
};
MetaValue类具有用于获取当前存储的变量值的各种Get函数,但最终会使每个查询值成为if / else if语句的一大块,以找出我要查找的值。
我还探讨了将值仅存储为字符串,并执行转换以获取不同的变体类型,但据我所知,这导致了一堆内部字符串解析和错误处理,这很不好,打开了一个带有浮点值的精度和数据丢失问题的老旧罐子,并且仍然无法消除上述if / else if问题的查询。
有人使用标准库实现或看到过更干净的方法可用于C ++变体数据类型吗?
从C ++ 17开始,有std::variant
。
[如果您还不能使用它,则可能需要std::variant
。 Boost.Variant(以及C ++ 17之前的版本,std::any
)提供了一种相似但截然不同的用于建模多态的类型。
仅作为附加指针,您可以查找“ std::any
”。
虽然Konrad的答案(使用现有的标准化解决方案)肯定比编写自己的易错版本更可取,但boost变体会产生一些开销,特别是在复制构造和内存方面。
您还可以使用更为C的解决方案,该解决方案在系统上的void *大小为double的大小,再加上要使用的类型的枚举。它相当干净,但是对于那些完全熟悉系统原始字节的人来说绝对是一个解决方案。
C ++ 17现在有了getType()
,这正是您想要的。
尽管问题已经回答了很长时间,但我想提一下,std::variant
也可以这样做。