C ++多态环缓冲区

时间:2017-12-07 10:38:17

标签: c++ circular-buffer

是否有一个库可以让我在支持入队和出列的缓冲区中存储公共基类型的对象?这就是我真正需要的,我不需要O(1)访问每个元素。允许每个对象可以具有不同的大小(多态环缓冲区)。 我可以使用vector基类型的指针,但在我看来这是一种矫枉过正。如果我使用这种环形缓冲区,我将不必为每个对象分配单独的内存。

2 个答案:

答案 0 :(得分:1)

正如@JTejedor所述,boost poly collection非常直接地解决了您的问题。

如果由于某种原因你不喜欢使用boost,可以编造一个简单的std::variant解决方案

template<typename Base, typename... Derived>
struct poly
{
    std::variant<Base, Derived...> var;

    template<typename... Args>
    poly(Args&&... args) : var{std::forward<Args>(args)...} {}

    auto& get()
    {
        auto id = [](auto& v) -> Base& { return v; };
        return std::visit(id, var);
    }

    operator Base&() { return get(); }
};

并将其用作

struct B {};
struct D1 : B {};
struct D2 : B { int i; };

void foo()
{
    using poly_t = poly<B, D1, D2>;

    std::vector<poly_t> vec;
    vec.push_back(B{});
    vec.push_back(D1{});
    vec.push_back(D2{});

    B& ref = vec.back();
}

Live

答案 1 :(得分:0)

您可以使用fread。在示例中,您可以存储指针intYourInterfaceClass*,而不是std::shared_ptr< YourInterfaceClass >

// Create a circular buffer with a capacity for 3 integers.
boost::circular_buffer<int> cb(3);

// Insert threee elements into the buffer.
cb.push_back(1);
cb.push_back(2);
cb.push_back(3);

int a = cb[0];  // a == 1
int b = cb[1];  // b == 2
int c = cb[2];  // c == 3

// The buffer is full now, so pushing subsequent
// elements will overwrite the front-most elements.

cb.push_back(4);  // Overwrite 1 with 4.
cb.push_back(5);  // Overwrite 2 with 5.

// The buffer now contains 3, 4 and 5.
a = cb[0];  // a == 3
b = cb[1];  // b == 4
c = cb[2];  // c == 5

// Elements can be popped from either the front or the back.
cb.pop_back();  // 5 is removed.
cb.pop_front(); // 3 is removed.

// Leaving only one element with value = 4.
int d = cb[0];  // d == 4

我在我的项目中使用它并且没有任何问题。