2011-07-05 10 views
0

私は、タイプFooのリストと違うサイズのタイプのバー*を持っています。どちらの型でも、描画順序のz座標でリストをソートすることができる位置決めシステムが実装されています(x、y、z値を持つPointはz値でPredicate関数未満でソートされます)。異なるタイプの2つのstd :: listsを組み合わせる:可能ですか?

上記以外は完全に異なります。リストを結合する方法はありますか?それで、すべてのz値をそれぞれの型の代わりに互いに比較できますか?

たとえば、すべてのFoosがソートされるか、すべてのバーがソートされます。すべてのFoosが描画されるか、すべてのバーが描画されます。これにより、BarがFooよりもzが小さい場合でも、その上に描画されます。明らかに意図された結果ではない。

これを入力している間に、私は気づきがありましたが、並列処理が行われますか?それぞれのリストを別々にソートしますが、それらをFoo、Bar、Foo、Barなどで交互に描画するか、同じ問題が発生しますか? z値にかかわらず他のものの上に描画するものはありますか?

ありがとうございました。

+1

I:あなたは2つの完全に独立したタイプを単一のリストを維持したいが持っている場合

foo_list.sort(); bar_list.sort(); auto fiter = foo_list.begin(), fend = foo_list.end(); auto biter = bar_list.begin(), bend = bar_list.end(); while(fiter != fend && biter != bend) { // draw whichever Foo or Bar is closest, and increment only that iterator. if((*fiter)->z_pos < (*biter)->z_pos) { (*fiter)->Draw(); ++fiter; } else { (*biter)->Draw(); ++biter; } } // reached the end of one of the lists. flush out whatever's left of the other. for(; fiter != fend; ++fiter) { (*fiter)->draw(); } for(; biter != bend; ++biter) { (*biter)->draw(); } 

あなたはまた、バリアントを使用することができますあなたのエピファニーがうまくいくと思う...それぞれのリストに対して別々のイテレータを保ち、常に、現在のアイテムが低いZ値を持つリストを描画して反復する。あなたが両方のリストの終わりに達するまで繰り返す。エホバの証人。 –

答えて

5

あなたはおそらくvirtual Draw()と、両方のタイプの位置を含むベースから継承した試してみてください:

struct Base 
{ 
    Point pos; 

    virtual ~Base() {} 
    virtual void Draw() = 0; 
}; 

struct Foo : base {}; 
struct Bar : base {}; 

std::list<Base*> list; 

//... 

list.sort([](Base *left, Base *right) 
{ 
    return left->pos.z < right->pos.z; 
}); 

for(auto iter = list.begin(), end = list.end(); iter != end; ++iter) 
{ 
    (*iter)->Draw(); 
} 

あなたはFooBarを描くの間で交互に、別々のリストを維持したい場合は動作しません。 Fooのうち2つが1つ前に来る場合は、Barとなります。

しかし、あなたは正しい道を考えています。描画しているときには、並べ替え、個別にして、二つのリストをマージすることができます

struct visitor 
{ 
    float operator()(Foo* f) const { return f->z_position; } 
    float operator()(Bar* b) const { return b->z_position; } 
}; 

std::list<boost::variant<Foo*, Bar*>> list; 

//... 

list.sort([](boost::variant<Foo*, Bar*> const &left, boost::variant<Foo*, Bar*> const &right) 
{ 
    return apply_visitor(visitor(), left) < apply_visitor(visitor(), right); 
}); 

for(auto iter = list.begin(), end = list.end(); iter != end; ++iter) 
{ 
    (*iter)->Draw(); 
} 
+0

今までそれを試してみてはいかがでしたか?個々にソートしてマージするのは面白かったです! :D洞察力ありがとう。 – Casey

関連する問題