gpt4 book ai didi

c++ - 在编译时强制执行正确的状态转换

转载 作者:行者123 更新时间:2023-11-28 06:07:51 25 4
gpt4 key购买 nike

我正在编写一些代码,根据一些传入数据创建特定格式的数据包,其中还包括时间戳(应该是生成进入数据包的第一位数据的时间)。在(简化的)高层次上,这看起来像:

template <typename T>
class packetizer
{
public:
set_payload(const T* data, uint16_t length, uint32_t timestamp);
};

有一个额外的要求是能够零碎地添加数据;像这样的东西:

uint16_t initial_data(const T* data, uint16_t length, uint32_t timestamp);
uint16_t append_data(const T* data, uint16_t length);

在这里,时间戳应该只添加一次,在 initial_data 调用中。这一切都有效,并且可以在运行时检查,但到目前为止,我一直在努力提供一个尽可能在编译时安全的 API——我想在编译时强制执行上述不变量。我考虑过这样做的一种方法是返回代理:

struct proxy_packetizer
{
private:
packetizer<T>& packet_ref;

public:
uint16_t append_data(const T* data, uint16_t length)
{
// forward call to packet_ref
}
};

template <typename T>
class packetizer
{
public:
proxy_packetizer initial_data(const T* data, uint16_t length, uint32_t timestamp);
};

which 的使用类似于:

packetizer p;
auto p2 = p.initial_data(data, length, timestamp);
p2.append_data(....);
auto pkt = p2.create_packet(...);

然而,这有点笨拙,而且仍然容易出错。如果我能以某种方式拥有一个看起来更像的 API,我更愿意:

packetizer p;
p.initial_data(data, length, timestamp);
p.append_data(...);
auto pkt = p.create_packet();

在编译时强制执行的地方:

  1. initial_data 为每个数据包调用一次且仅调用一次。
  2. append_data 只能在 initial_data 调用后调用。
  3. create_packet 重置它(因此必须再次调用 initial_data)。

是否有任何编译时方法来强制执行这些类型的状态转换?

最佳答案

我同意@TonyD 关于采用 RAII 方法的评论。这个想法是将 packetizer::initial_data(...) 转换为构造函数 packetizer::packetizer(...)。这就是 timestamp 将只设置一次的方式:

template <typename T>
class packetizer
{
public:
packetizer(const T* data, uint16_t length, uint32_t timestamp);

uint16_t append_data(const T* data, uint16_t length);
};

由于初始数据可能在运行时的任何时候出现,您可以使用 operator new 来实现相同的目的:

std::unique_ptr<packetizer<T>> packetizer = new Packetizer<T>(data, length, timestamp);
...
packetizer->append_data(data, length);

从问题中提到的任何内容来看,我都不能对 set_payload() 说太多;但如果它容易出错,那么我们最好通过更改设计来消除它。

关于c++ - 在编译时强制执行正确的状态转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32002200/

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