重置循环缓冲区中的元素

时间:2015-05-04 04:23:25

标签: arrays c++11 circular-buffer stdarray

我被要求在C ++中实现一个循环缓冲区,该缓冲区采用未指定类型。我假设泛型类型是基本类型。 (或者它应该考虑非基本类型?)对于缓冲区,我使用基本数组,例如T [] 使用删除来初始化并销毁它。

我已经实现了缓冲类,并在具有预期输出的整数上进行了测试。但它不适用于std::string。问题是,当我弹出缓冲区时,我通过将其设置为零来清除元素,并且编译器抱怨这样做是不明确的。因此,我需要一种通用的方法来清除元素,我认为std::array可能支持此功能,但我在文档中找不到它。

是否有通用的方法来清除std :: array或基本数组中的元素,或者std :: allocator是唯一的选项吗?或者,如果我完全走错方向,我应该如何实现pop方法重置第一个元素并将前索引增加到下一个元素

提前致谢!

如果有帮助,以下是我的相关代码:

template<class T> T CircularBuffer<T>::pop_front()
{
    if (_size == 0)
        return 0;
    T value = buffer[_front];
    buffer[_front] = 0;
    if (--_size == 0)
    {
        _front = -1;
        _back = -1;
    }
    else
    {
        _front = (_front + 1) % _capacity;
    }
    return value;
}

2 个答案:

答案 0 :(得分:2)

circular buffer中你并没有真正从内存中删除元素,否则Jagannath指出std::deque是你的选择。你更喜欢&#34;重置&#34;已经弹出的元素。

buffer[_front] = 0;

表示&#34;将0分配给T&#34;。 T = std::string有两种方法可以解释这种模糊性。有点简化它们看起来像这样:

std::string std::string::operator=(char c);

std::string std::string::operator=(const char *cPtr);

我想你不想要任何这个,所以我的选择是(如T.C.所写):

buffer[_front] = T();

此外(并且出于非常类似的原因)

if (_size == 0)
    return 0;

也是一个问题,因为它会崩溃,请注意:

std::string a = circularBuffer.pop_front(); // crashes on empty buffer

可以 return T(),但更干净的方式肯定会抛出std::out_of_range例外。

答案 1 :(得分:1)

您可以这样做的一种方法是将内存视为原始内存,并使用放置新的和手动析构函数调用。

看起来像这样:

void push(const T& val)
{
    new ( data + sizeof(T)*idx++ ) T { val };
}

void pop()
{
    ( (T*) (data + sizeof(T)*--idx) ) -> ~T();
}