我开始编写循环缓冲库,只是为了好玩。我遇到了一个特殊的问题:
{{1}}
它返回类型T,但是当CB为空并且用户尝试使用pop()时的情况呢?返回nullptr是没有意义的,因为例如nullptr不能转换为double。显然,可以抛出异常,但是有一种更加语义友好的方式吗?
编辑:通过"语义友好"我的意思是:
当推入完整的CB时,抛出异常是很自然的。异常应该阻止程序崩溃,因为新元素没有足够的内存。在弹出一个空的CB时抛出异常对我来说似乎是在语义上,因为程序不会崩溃。但如果它是唯一可用的选项,请告诉我。
答案 0 :(得分:1)
这是std::optional
或boost::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.
});
你可以扩展这个概念,同时对“爆发失败”进行额外的延续。情况下。