2017-12-07 6 views
1

エンキューとデキューをサポートするバッファに共通基本型のオブジェクトを格納できるライブラリはありますか?それは私が必要とするすべてのものです、私はO(1)各要素へのアクセスを必要としません。各オブジェクトは異なるサイズ(多形リングバッファ)を持つことができます。 基本タイプのポインタのvectorを使うことができましたが、それは私には過剰なものです。この種のリングバッファを使用すると、オブジェクトごとに別々のメモリを割り当てる必要はありません。C++多形リングバッファ

+3

'vector'には何の問題がありますか?あなたはそれが過度だと思いますか?あなたが提案する解決策は私には似ています。 BTWライブラリ要求はOTです。 –

+0

ベクトルソリューションはそれほど悪くはありません。ライブラリはおそらく同様のことを行い、追加のライブラリが必要です。 – allo

+1

boost [poly_collection](http://www.boost.org/doc/libs/develop/doc/html/poly_collection.html)について考えると、これは 'vector'よりも優れた解決策です。なぜなら、同じクラス要素を連続的に割り当てるためですそれは特に多型の使用のために準備ができています。 – JTejedor

答えて

1

@JTejedorで述べたように、boost poly collectionは問題をかなり直接解決します。あなたがブーストを好きではないいくつかの理由で、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(); } 
}; 

をでっち上げすることができ、あなたがBoost.Circular Bufferを使用することができ

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

0

としてそれを使用している場合

。例ではintの代わりに、ポインタYourInterfaceClass*または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 

これは私のプロジェクトで使用しており、問題はありませんでした。