gpt4 book ai didi

c++ - 现代 C++ 中具有可选成员的结构

转载 作者:可可西里 更新时间:2023-11-01 18:38:14 26 4
gpt4 key购买 nike

我们继承了旧代码,我们正在将其转换为现代 C++,以获得更好的类型安全性、抽象和其他好处。我们有许多具有许多可选成员的结构,例如:

struct Location {
int area;
QPoint coarse_position;
int layer;
QVector3D fine_position;
QQuaternion rotation;
};

重要的一点是所有成员都是可选的。 Location 的任何给定实例中至少会出现一个,但不一定全部出现。可能的组合比原始设计者显然发现用单独的结构表达每个组合更方便。

结构以这种方式反序列化(伪代码):

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;
// etc.
};

此解决方案使设计缺陷现代化,而不是修复它。

我们想到像这样使用 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;
};
// etc.
std::variant<Has_Area_and_Coarse,
Has_Area_and_Coarse_and_Fine /*, etc.*/> data;
};

此解决方案使非法状态无法表示,但在成员变量的多个组合是可能的情况下不能很好地扩展。此外,我们不希望通过指定 Has_Area_and_Coarse 进行访问,而是通过更接近 loc.fine_position 的方式进行访问。

这个问题有没有我们没有考虑过的标准解决方案?

最佳答案

mixins 呢?

struct QPoint {};
struct QVector3D {};
struct Area {
int area;
};
struct CoarsePosition {
QPoint coarse_position;
};
struct FinePosition {
QVector3D fine_position;
};
template <class ...Bases>
struct Location : Bases... {
};

Location<Area, CoarsePosition> l1;
Location<Area, FinePosition> l2;

关于c++ - 现代 C++ 中具有可选成员的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49292823/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com