将可选属性表示为C++;班级成员 我正在基于模式生成C++代码。存在实体,每个实体包含属性,每个属性具有相应的数据类型。现在的问题是其中一些属性是“可选的”,这意味着它们不必是类声明的一部分。但是,C++中,某个成员不是类成员,也不是类成员,没有“可选数据成员”之类的概念。p>

将可选属性表示为C++;班级成员 我正在基于模式生成C++代码。存在实体,每个实体包含属性,每个属性具有相应的数据类型。现在的问题是其中一些属性是“可选的”,这意味着它们不必是类声明的一部分。但是,C++中,某个成员不是类成员,也不是类成员,没有“可选数据成员”之类的概念。p>,c++,class,schema,code-generation,C++,Class,Schema,Code Generation,实体将是类名,属性将是类成员。我不确定如何表示被标记为“可选”的现有C++概念。 < P>正则答案是。这是一种语义准确的方法,用于表示模型中可能存在或不存在的值 创建这样一个模型时,对于模式中的每个可选字段,您都会生成相应的std::optional-wrapped条目。然后,在反序列化时,可以使用std::none标记缺少的条目,并且在访问过程中,客户端代码必须检查是否存在实际值1 但是,如果对象很大,并且希望避免不必要地存储空空间2,那么下一种选择是std::unique_ptr。它具有指针

实体将是类名,属性将是类成员。我不确定如何表示被标记为“可选”的现有C++概念。

< P>正则答案是。这是一种语义准确的方法,用于表示模型中可能存在或不存在的值

创建这样一个模型时,对于模式中的每个可选字段,您都会生成相应的
std::optional
-wrapped条目。然后,在反序列化时,可以使用
std::none
标记缺少的条目,并且在访问过程中,客户端代码必须检查是否存在实际值1

但是,如果对象很大,并且希望避免不必要地存储空空间2,那么下一种选择是
std::unique_ptr
。它具有指针语义的缺点,但对于这种情况,它仍然是一个有效的工具

如果成员是非常动态的,例如,可能的集合有几十个或数百个,但典型的利用率只会看到几个,那么键值存储(例如
std::map
)可能是一个更好的主意;然后您只能存储一种类型的值。如果将
std::variant
用作映射值类型,则这可能会有所缓解,这为您提供了多种可能性中的一种,或者
std::any
,它可以在丢失类型安全性的同时有效地保存任何内容

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


1如果客户机代码需要
T
,并且对字段的访问为其提供了
可选
,则展开步骤将/应检查是否存在实际值。这是使用
可选
的主要原因


2
sizeof(可选)
通常为
sizeof(S)+1
,但由于对齐规则,可能会变大。本文的第节很好地展示了它。

std::optional
或指针?std::optional到底做什么?它是C++17规范的一部分。我想我还不会使用C++17规范。@nmd_07 C++17是最新发布的规范,应该用于新代码。而
可选
做的正是你所想的。@BartekBanachewicz我更准确地说“语义正是你所想的”。从名字上看,幕后的东西一点也不明显。它是堆分配还是包含可选对象?它使用sentinel值还是需要额外的空间?它是否依赖于
T
(甚至是可定制的)?从语义角度看,这并不重要,但您在回答中演示了结果权衡。@user463035818-使用
std::vector
可能是一个不错的技巧,但它是错误的抽象。它最终迫使维护人员在处理这两者时跟踪哪些向量是实向量,哪些只是“可选”字段。这不是一个好的代码库。唯一指针更接近于可选指针作为抽象。@StoryTeller当然,我会用
false\u std17\u包装它,因为它只有\u std11::optional
,具有与
std::optional
类似的接口)@USE463035818也可以包装<代码> STD::UNQuyGYPTR <代码>,也就是C++ 11。FWW甚至提到了一个应该考虑不使用可选的场景。members@Eljay-只表明你永远不会真正杀死一个坏主意