如何在C ++中存储变体数据

问题描述 投票:20回答:5

我正在创建一个类,该类存储有关特定数据源的元数据。元数据是在树中构造的,与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++ variant
5个回答
30
投票

从C ++ 17开始,有std::variant

[如果您还不能使用它,则可能需要std::variantBoost.Variant(以及C ++ 17之前的版本,std::any)提供了一种相似但截然不同的用于建模多态的类型。

仅作为附加指针,您可以查找“ std::any”。


12
投票

虽然Konrad的答案(使用现有的标准化解决方案)肯定比编写自己的易错版本更可取,但boost变体会产生一些开销,特别是在复制构造和内存方面。


9
投票

您还可以使用更为C的解决方案,该解决方案在系统上的void *大小为double的大小,再加上要使用的类型的枚举。它相当干净,但是对于那些完全熟悉系统原始字节的人来说绝对是一个解决方案。


7
投票

C ++ 17现在有了getType(),这正是您想要的。


4
投票

尽管问题已经回答了很长时间,但我想提一下,std::variant也可以这样做。

© www.soinside.com 2019 - 2024. All rights reserved.