将可选属性表示为C ++类成员 [英] Represent an optional attribute as a C++ class member
问题描述
我正在基于架构生成C ++代码。存在实体,每个实体包含一个或多个属性,每个属性具有对应的数据类型。现在的问题是这些属性中的一些是可选的,这意味着它们不必成为类声明的一部分。但是,在C ++中,某些东西要么是类的成员,要么不是类的成员,没有诸如可选数据成员之类的概念。
I am generating C++ code based on a schema. There are entities and each entity contain attribute(s) with each attribute having a corresponding data type. Now the problem is some of these attributes are "optional", meaning that they do not have to be part of the class declaration. However, in C++, something is either a member of class or not a member of class, there is no concept such as "optional data member".
实体是类名,属性是类成员。我不确定如何表示现有C ++概念中标记为可选的属性。
Entities will be the class names, and attributes will be the class members. I am not sure how I can represent attributes marked as "optional" the existing C++ concepts.
推荐答案
典型答案是 std :: optional
。这是表达模型中可能存在或可能不存在的值的语义上准确的方法。
The canonical answer is std::optional
. It is a semantically accurate way to express a value that might or might not exist in a model.
创建此类模型时,对于架构中的每个可选字段,您都可以生成相应的 std :: optional
包装的条目。然后,在反序列化时,可以使用 std :: none
标记缺少的条目,并且在访问过程中,客户端代码必须检查实际值 1 的存在。
When creating such a model, for each optional field in a schema, you generate a corresponding std::optional
-wrapped entry. Then, when deserializing, you can use std::none
to mark a missing entry, and it during accessing, the client code must check for the existence of actual value1.
如果对象很大,并且您要避免不必要地存储空白 2 ,下一个替代方法是 std :: unique_ptr
。
If your objects are large, though, and you want to avoid storing the empty space unnecessarily2, the next alternative is std::unique_ptr
. It has a downside of having pointer semantics, but otherwise remains a valid tool for such a case.
如果成员非常是动态的,例如,它具有指针语义的缺点。可能的设置是几十个或几百个,但是典型的利用率只有少数几个,键值存储(例如 std :: map
)可能是一个更好的主意;那么您就只能存储一种类型的值。将 std :: variant
用作地图值类型可能会有所缓解,这为您提供了多种可能性之一,或者 std ::任何
,可以有效地容纳任何东西,同时又失去类型安全性。
If the members are very dynamic, e.g. the possible set is in dozens or hundreds, but typical utilization will see just a few, a key-value store (such as std::map
) might be a better idea; then you're limited to store just one type of a value. This might be mitigated a bit with std::variant
being used as the map value type, which gives you one of many possibilities, or std::any
, which can effectively hold anything while losing type safety.
最终的决定将取决于您的确切型号和使用特性。
The decision will ultimately depend on your exact model and usage characteristics.
1 如果客户端代码期望 T
,并且对字段的访问使它们具有 optional< T>
,展开步骤将/将检查实际值的存在。这是使用可选
的主要原因。
1 If the client code expects T
, and the access for a field gives them optional<T>
, the unwrapping step will/shall check for the existence of an actual value. This is the main reason optional
is used.
2 sizeof(optional< S>)
通常为 sizeof(S)+ 1
,但由于对齐规则而可能变大。本文的 Performance& Memory 部分很好地展示了它。
2 sizeof(optional<S>)
will most commonly be sizeof(S) + 1
, but can get bigger because of the alignment rules. Performance&Memory section of this article shows it nicely.
这篇关于将可选属性表示为C ++类成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!