将可选属性表示为 C++ class 成员

Represent an optional attribute as a C++ class member

我正在基于模式生成 C++ 代码。有实体,每个实体都包含属性,每个属性都有相应的数据类型。现在的问题是其中一些属性是 "optional",这意味着它们不必是 class 声明的一部分。但是,在C++中,something要么是class的成员,要么不是class的成员,没有"optional data member"这样的概念。

实体将是 class 名称,属性将是 class 成员。我不确定如何表示标记为 "optional" 现有 C++ 概念的属性。

标准答案是 std::optional。它是表达模型中可能存在或不存在的值的语义准确方式。

创建此类模型时,对于架构中的每个可选字段,您都会生成相应的 std::optional 包装条目。然后,在反序列化时,可以使用 std::none 标记丢失的条目,并且在访问期间,客户端代码 必须 检查实际值是否存在 1.

但是,如果您的对象很大,并且您想避免不必要地存储空的 space2,下一个选择是 std::unique_ptr。它具有指针语义的缺点,但在其他方面仍然是这种情况下的有效工具。

如果成员非常动态,​​例如可能的集合有几十个或几百个,但典型的利用率只会看到几个,键值存储(例如 std::map)可能是一个更好的主意;那么您只能存储一种类型的值。使用 std::variant 作为映射值类型可能会稍微缓解这种情况,这为您提供了多种可能性之一,或者 std::any,它可以在失去类型安全性的同时有效地容纳任何东西。

最终将取决于您的确切型号和使用特征。


1 如果客户端代码期望 T,并且对字段的访问给他们 optional<T>,则解包步骤 will/shall 检查因为实际价值的存在。这是使用 optional 的主要原因。

2 sizeof(optional<S>) 最常见的是 sizeof(S) + 1,但由于对齐规则可以变得更大。 Performance&Memory 这篇文章的部分很好地展示了它。