你可以嘗試有兩種類型,從包括位置基本繼承,或許還有一個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();
}
如果你想保持獨立的名單,繪圖Foo
和Bar
將無法正常工作之間交替如果Foo
中的兩個會出現在一個Bar
之前。
但是你正在思考正確的軌道。同時提請您可以排序單獨然後合併兩個列表:
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();
}
你也可以使用一個變種,如果你想只保留一個名單,但有兩個完全不同的類型:
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();
}
我認爲你的頓悟能夠很好地工作......爲每個列表保留一個單獨的迭代器,並且始終在「當前項目」具有較低Z值的列表上繪製並隨後迭代。重複,直到您到達兩個列表的末尾。 Et瞧。 –