2011-07-05 37 views
0

我有一個類型爲Foo *的std :: list和另一個不相等大小的Bar *類型的列表。這兩種類型都實現了一個定位系統,該系統允許按照繪製順序的z座標對列表進行排序(實際上只是一個x,y,z值的點,並且它們的排序順序小於Predicate函數的z值)。結合兩個不同類型的std :: lists:可能嗎?

除了上面提到的,它們是完全不同的。有沒有一種方法來組合這些列表,以便我可以比較所有的z值而不僅僅是他們自己的類型?

現在,例如,對所有的Foos進行排序,或者對所有的Bars進行排序;那麼要麼所有的Foos被繪製,要麼所有的Bars都被繪製。即使酒吧的Z比Foo低,它也會被繪製在最上面。顯然不是預期的後果。

打字時,我確實有一個頓悟,會並行處理的工作?分開排序每個列表,然後交替繪製它們,Foo,Bar,Foo,Bar等,否則會導致相同的問題?不管z值如何繪製其他人?

謝謝。

+1

我認爲你的頓悟能夠很好地工作......爲每個列表保留一個單獨的迭代器,並且始終在「當前項目」具有較低Z值的列表上繪製並隨後迭代。重複,直到您到達兩個列表的末尾。 Et瞧。 –

回答

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中的兩個會出現在一個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(); 
} 
+0

到現在爲止還沒有機會對它進行測試,單獨排序和合並繪圖效果很好! :D感謝您的洞察力。 – Casey

相關問題