重置循环缓冲区中的元素

Reset an element in a circular buffer

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

我已经实现了缓冲区 class 并在具有预期输出的整数上对其进行了测试。但它不适用于 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;
}

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

它可能看起来像这样:

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

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

circular buffer you do not really remove elements from memory, otherwise as Jagannath pointed out std::deque 中是您的选择。你更喜欢"reset"已经弹出的元素

buffer[_front] = 0;

表示"assign 0 to a T"。 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 异常。