We inherited the old code, which we translate into modern C ++, to get better security, abstraction and other useful properties. We have several structures with many optional members, for example:
struct Location {
int area;
QPoint coarse_position;
int layer;
QVector3D fine_position;
QQuaternion rotation;
};
The important point is that all members are optional. At least one will be present at any given location, but not necessarily all. More combinations are possible than the original developer, which is apparently convenient for expression with separate structures for each.
Structures are deserialized in this way (pseudo-code):
Location loc;
// Bitfield expressing whether each member is present in this instance
uchar flags = read_byte();
// If _area_ is present, read it from the stream, else it is filled with garbage
if (flags & area_is_present)
loc.area = read_byte();
if (flags & coarse_position_present)
loc.coarse_position = read_QPoint();
etc.
, getter , , Location.
. , , , . , , , , - .
std:: optional:
struct Location {
std::optional<int> area;
std::optional<QPoint> coarse_location;
};
, .
std:: variant :
struct Location {
struct Has_Area_and_Coarse {
int area;
QPoint coarse_location;
};
struct Has_Area_and_Coarse_and_Fine {
int area;
QPoint coarse_location;
QVector3D fine_location;
};
std::variant<Has_Area_and_Coarse,
Has_Area_and_Coarse_and_Fine > data;
};
, , -. , , Has_Area_and_Coarse, - loc.fine_position.
, ?