我正在基于架构生成C ++代码。存在实体,每个实体包含一个或多个属性,每个属性具有对应的数据类型。现在的问题是,其中某些属性是“可选的”,这意味着它们不必成为类声明的一部分。但是,在C ++中,某些东西要么是类的成员,要么不是类的成员,没有诸如“可选数据成员”之类的概念。
实体将是类名称,而属性将是类成员。我不确定如何表示现有C ++概念中标记为“可选”的属性。
答案 0 :(得分:8)
规范答案为std::optional
。这是表达模型中可能存在或可能不存在的值的语义上准确的方法。
创建此类模型时,将为架构中的每个可选字段生成一个对应的std::optional
包装的条目。然后,在反序列化时,可以使用std::none
标记缺少的条目,并且在访问过程中,客户端代码必须检查是否存在实际值 1
但是,如果对象很大,并且要避免不必要地存储空白空间 2 ,则下一个替代方法是std::unique_ptr
。它具有指针语义的缺点,但在其他情况下仍然是有效的工具。
如果成员动态非常动态,例如可能的设置是几十个或几百个,但是典型的利用率只有少数几个,键值存储(例如std::map
)可能是一个更好的主意;那么您就只能存储一种类型的值。将std::variant
用作映射值类型可能会有所缓解,这为您提供了多种可能性中的一种,或者std::any
可以有效保留任何内容而又失去类型安全性。
最终决定将取决于您的确切型号和使用特性。
1 如果客户端代码期望T
,并且对字段的访问使它们optional<T>
,则展开步骤将/将检查是否存在实际值。这是使用optional
的主要原因。
2 sizeof(optional<S>)
最通常为sizeof(S) + 1
,但由于对齐规则而可能变大。本文的Performance&Memory部分对此进行了很好的展示。