C++ 中的通用循环缓冲区实现
Generic circular buffer implementation in C++
我开始编写循环缓冲区库,只是为了好玩。我遇到了一个特殊问题:
template < class T >
T CircularBuffer<T>::pop()
它 returns 类型 T,但是当 CB 为空并且用户尝试使用 pop() 时会怎样?返回 nullptr 没有意义,因为 nullptr 不能转换为 double。显然,可以抛出异常,但有没有更语义友好的方式来抛出异常呢?
编辑:"semantically friendly" 我的意思是:
推入完整的CB时,抛出异常是很自然的。异常应该防止程序崩溃,因为没有足够的内存用于新元素。在弹出一个空的 CB 时抛出异常对我来说似乎是语义上的,因为程序不会崩溃。但如果这是唯一可用的选项,请告诉我。
这是 std::optional
or boost::optional
的完美用例 - 它们 类 存储值 或 空状态。
您可以将签名更改为:
template < class T >
std::optional<T> CircularBuffer<T>::pop()
你的合同将是这样的:
如果缓冲区为空,则返回std::nullopt
。
否则返回一个非空std::optional<T>
包含head元素
或者,考虑采用一个 "continuation" 函数,该函数仅在 pop 成功时才会被调用。示例:
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.
});
您可以通过对 "pop failure" 案例进行额外的延续来扩展这个概念。
我开始编写循环缓冲区库,只是为了好玩。我遇到了一个特殊问题:
template < class T >
T CircularBuffer<T>::pop()
它 returns 类型 T,但是当 CB 为空并且用户尝试使用 pop() 时会怎样?返回 nullptr 没有意义,因为 nullptr 不能转换为 double。显然,可以抛出异常,但有没有更语义友好的方式来抛出异常呢?
编辑:"semantically friendly" 我的意思是:
推入完整的CB时,抛出异常是很自然的。异常应该防止程序崩溃,因为没有足够的内存用于新元素。在弹出一个空的 CB 时抛出异常对我来说似乎是语义上的,因为程序不会崩溃。但如果这是唯一可用的选项,请告诉我。
这是 std::optional
or boost::optional
的完美用例 - 它们 类 存储值 或 空状态。
您可以将签名更改为:
template < class T >
std::optional<T> CircularBuffer<T>::pop()
你的合同将是这样的:
如果缓冲区为空,则返回
std::nullopt
。否则返回一个非空
std::optional<T>
包含head元素
或者,考虑采用一个 "continuation" 函数,该函数仅在 pop 成功时才会被调用。示例:
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.
});
您可以通过对 "pop failure" 案例进行额外的延续来扩展这个概念。