2010-06-08 49 views
4

Hy there,Iterator for boost ::變種

我在嘗試改編現有的代碼來增強:: variant。這個想法是使用boost :: variant作爲異構向量。問題是其餘的代碼使用迭代器訪問向量的元素。有沒有辦法與迭代器一起使用boost :: variant?

我已經試過

typedef boost::variant<Foo, Bar> Variant; 
std::vector<Variant> bag; 
std::vector<Variant>::iterator it; 
for(it= bag.begin(); it != bag.end(); ++it){ 

cout<<(*it)<<endl; 
} 

但沒有奏效。

編輯:謝謝你的幫助!但在我的設計中,我需要從列表中獲取一個元素並將其傳遞給代碼的其他部分(而且這可能很糟糕,因爲我使用的是GSL)。使用迭代器的想法是我可以將迭代器傳遞給函數,並且該函數將對來自該特定元素的返回數據進行操作。我看不到如何使用for_each來做到這一點。我需要做類似的事情:

for(it=list.begin(); it!=list.end();++it) { 
    for(it_2=list.begin(); it_2!=list.end();++it_2) { 

    if(it->property() != it_2->property()) { 

     result = operate(it,it_2); 

     } 
    } 

} 

謝謝!

回答

8

那當然有。解引用迭代器自然會產生一個boost::variant<...>引用或const引用。

但是這意味着代碼的其餘部分應該是變體感知的。特別是使用boost::static_visitor來對變體執行操作。

編輯

輕鬆!

struct Printer: boost::static_visitor<> 
{ 
    template <class T> 
    void operator()(T const& t) const { std::cout << t << std::endl; } 
}; 

std::for_each(bag.begin(), bag.end(), boost::apply_visitor(Printer()); 

注意如何編寫訪問者自動生成STL算法的謂詞,miam!現在

,返回值的問題:

class WithReturn: boost::static_visitor<> 
{ 
public: 
    WithReturn(int& result): mResult(result) {} 

    void operator()(Foo const& f) const { mResult += f.suprise(); } 
    void operator()(Bar const& b) const { mResult += b.another(); } 

private: 
    int& mResult; 
}; 


int result; 
std::for_each(bag.begin(), bag.end(), boost::apply_visitor(WithReturn(result))); 

編輯2:

這很容易,但確實需要一點教練:)的

首先,我們此言有兩種不同的操作:!=operate

struct PropertyCompare: boost::static_visitor<bool> 
{ 
    template <class T, class U> 
    bool operator()(T const& lhs, U const& rhs) 
    { 
    return lhs.property() == rhs.property(); 
    } 
}; 

struct Operate: boost::static_visitor<result_type> 
{ 
    result_type operator()(Foo const& lhs, Foo const& rhs); 
    result_type operator()(Foo const& lhs, Bar const& rhs); 
    result_type operator()(Bar const& lhs, Bar const& rhs); 
    result_type operator()(Bar const& lhs, Foo const& rhs); 
}; 

for(it=list.begin(); it!=list.end();++it) { 
    for(it_2=list.begin(); it_2!=list.end();++it_2) { 

    if(!boost::apply_visitor(PropertyCompare(), *it, *it_2)) { 

     result = boost::apply_visitor(Operate(), *it, *it_2)); 

    } 

    } 
} 

因爲這個if因爲每個都不是那麼好。如果你能以某種方式將if歸入operate,那麼它就會起作用。

另請注意,我傳遞的不是迭代器,而是引用。

+0

boost :: static_visitor可以很好地對元素進行操作,但在類必須返回一些數據時不起作用。我已經嘗試使用boost :: ptr_vector >的迭代器,但類似的東西沒有工作: typedef boost :: variant Variant; std :: vector 包; std :: vector ::迭代器它; for(it = bag.begin(); it!= bag。結束(); ++ it){ cout <<(* it)<< endl; } – Ivan 2010-06-10 22:30:25

+0

編輯條目來說明使用。 – 2010-06-11 06:34:12

+0

非常感謝。仍然試圖將這個概念適應於我現有的代碼,並且變化太大。上面的新編輯。 – Ivan 2010-06-11 16:54:23

相關問題