2011-04-16 101 views
11

我有一個值序列,我想傳遞給一對需要(iterator begin, iterator end)對的函數。但是,我只希望處理原始序列中的每個第二個元素。跳過迭代器

使用Standard-Lib/Boost創建一個允許我傳入原始序列的迭代器外觀是否有很好的方法?我想到了這樣簡單的東西,它已經存在於boost迭代器或範圍庫中,但我沒有找到任何東西。

或者我錯過了另一個完全明顯的方式來做到這一點?當然,我知道我總是可以選擇將值複製到另一個序列,但這不是我想要做的。

編輯:我知道filter_iterator,但它對值進行過濾 - 它不會改變迭代的進展方式。

+0

Ia問同一主題稍微不同的問題:http://stackoverflow.com/questions/3046747/c-stl-selective-iterator,Bt我特別要求沒有提升,不是很有幫助然後:( – rubenvb 2011-04-16 10:59:39

回答

2

這是Boost的filter iterator。這正是你想要的。

更新:對不起,讀錯了。下面是加速所有迭代器funkiness的列表:

http://www.boost.org/doc/libs/1_46_1/libs/iterator/doc/#specialized-adaptors

我覺得有超載operator++的兩倍遞增底層迭代器值一個普通iterator_adaptor是你所需要的。

+0

不,這是不。過濾器迭代器對值進行謂詞過濾 - 但我想在迭代器上有一個謂詞(如果你想把它當作過濾)。基本上,我只想'++ ='作爲'++'給我的內部運營商 – ltjax 2011-04-16 15:28:01

+0

,問題是應用(在實現中)operator ++兩次可以結束容器,而不檢查跳過元素是否已經結束)迭代器。 Althogh我有一個for循環記住(skip_iterator it = v.begin(); it!= v.end(); ++ it){} – alfC 2011-08-05 18:58:36

+2

alfC:你需要檢查'it!= end'在運算符++'內部,在第二次調用迭代器的'operator ++'之前。 – rubenvb 2011-08-06 09:15:01

3
struct TrueOnEven { 
template< typename T > 
bool operator()(const T&) { return mCount++ % 2 == 0; } 
TrueOnEven() : mCount(0) {} 
private: 
    int mCount; 
}; 

int main() { 
std::vector<int> tVec, tOtherVec; 
... 
typedef boost::filter_iterator< TrueOnEven, int > TakeEvenFilterType; 

std::copy( 
    TakeEvenFilterType(tVec.begin(), tVec.end()), 
    TakeEvenFilterType(tVec.end(), tVec.end()), 
    std::back_inserter(tOtherVec)); 
} 

說實話,這是非常好的和直觀的東西。我寫了一個簡單的「調查員」庫包括集成懶的查詢,以避免像上面的大雜燴。它允許你寫:

Query::From(tVec.begin(), tVec.end()) 
.Skip<2>() 
.ToStlSequence(std::back_inserter(tOtherVec)); 

其中Skip<2>基本上實例化一個廣義的「過濾器」,它跳過每第N個(以這種情況下每秒)元素...

乾杯,

保羅

+0

+1認識到這只是一個愚蠢的黑客攻擊。它還對內部算法如何使用迭代器以及filter_iterator如何使用謂詞做出了許多假設。例如,如果'operator()'對於一個給定的迭代器計算兩次,那麼所有事情都不同步。 – ltjax 2011-04-16 15:30:59

+0

好吧,嚴格來說,它是,如果filter_iterator分類爲除「std :: input_iterator」或「boost :: SinglePass」以外的其他任何內容。你應該寫一個完整的'skipping_iterator',這看起來很難...... – 2011-04-17 08:20:26