【发布时间】:2019-09-04 07:43:34
【问题描述】:
我的任务是完善编解码器库的界面。我们使用的是 C++17,我只能使用标准库(即没有 Boost)。目前,有一个Decoder 类,大致如下:
class Decoder : public Codec {
public:
struct Result {
vector<uint8_t>::const_iterator new_buffer_begin;
optional<Metadata> metadata;
optional<Packet> packet;
};
Result decode(vector<uint8_t>::const_iterator buffer_begin,
vector<uint8_t>::const_iterator buffer_end);
private:
// irrelevant details
};
调用者实例化一个Decoder,然后通过
从文件中读取一大块数据(但将来可能会有其他来源),并将其附加到
vector<uint8_t>。调用
decode函数,传递其向量的迭代器。如果返回的
Result的new_buffer_begin与传递给decode的buffer_begin相同,这意味着缓冲区中没有足够的数据来解码任何内容,调用者应该返回第 1 步。否则,调用者会使用已解码的Metadata或Packet对象,并返回第 2 步,使用new_buffer_begin进行下一次传递。
我不喜欢这个界面并需要帮助改进的地方:
使用
vector<uint8_t>::const_iterator似乎过于具体。有没有更通用的方法不强制调用者使用vector?我正在考虑只使用 C 风格的界面;uint8_t *和长度。有没有相当通用的 C++ 替代方案?如果有足够的数据来解码某些东西,那么只有
metadata或packet会有一个值。我认为std::variant或 2 个回调(每种类型一个)将使此代码更具自我记录性。我不确定哪个更惯用。各有什么优缺点,有没有更好的方法?
【问题讨论】:
-
Is there a C++ alternative that's fairly generic?模板。 -
typedef vector<uint8_t>::const_iterator it_t;或using it_t= vector<uint8_t>::const_iterator;会更干净。 -
我喜欢回调方法,为产生的每种结果传递一个带有回调的消费者对象。当方法返回时,您保证最多调用一个回调。但是你也可以有一个异步变体。 API 可以通过向消费者添加更多回调来发展。 std::variant 也不错,但可能需要用户检查哪一个可用(实际上并没有从两个选项改变)。
标签: c++ c++17 binary-data idioms