C ++中的通用循环缓冲区实现

时间:2017-06-11 09:52:34

标签: c++ circular-buffer

我开始编写循环缓冲库,只是为了好玩。我遇到了一个特殊的问题:

{{1}}

它返回类型T,但是当CB为空并且用户尝试使用pop()时的情况呢?返回nullptr是没有意义的,因为例如nullptr不能转换为double。显然,可以抛出异常,但是有一种更加语义友好的方式吗?

编辑:通过"语义友好"我的意思是:

当推入完整的CB时,抛出异常是很自然的。异常应该阻止程序崩溃,因为新元素没有足够的内存。在弹出一个空的CB时抛出异常对我来说似乎是在语义上,因为程序不会崩溃。但如果它是唯一可用的选项,请告诉我。

1 个答案:

答案 0 :(得分:1)

这是std::optionalboost::optional的完美用例 - 它们是将值存储为空状态的类。

您可以将签名更改为:

template < class T >
std::optional<T> CircularBuffer<T>::pop()

你的合同将是:

  • 如果缓冲区为空,则会返回std::nullopt

  • 否则,将返回包含head元素的非空std::optional<T>

或者,考虑采取一个&#34;继续&#34;只有在弹出成功时才会调用的函数。例如:

template < class F >
decltype(auto) CircularBuffer<T>::pop(F&& continuation);

用法:

some_circular_buffer.pop([](auto popped_item)
{
    // I will only be called if the pop was successful.
});

你可以扩展这个概念,同时对“爆发失败”进行额外的延续。情况下。