2012-02-22 84 views
3

使用隨機訪問迭代器,可以通過簡單地執行iter + = n然後使用container.end()而不是!= container.end()來更改跨度長度。作爲循環結束條件:使用非隨機訪問迭代器的非單元迭代器跨度

#include <iostream> 
#include <vector> 

int main(int argc, char *argv[]) 
{ 
    typedef std::vector<float> VectorType; 
    typedef VectorType::const_iterator IteratorType; 

    VectorType v; 
    for(unsigned int i = 0; i < 11; ++i) 
    { 
    v.push_back(i); 
    } 

    for(IteratorType iter = v.begin(); iter < v.end(); iter += 2) 
    { 
    std::cout << " " << *iter; 
    } 

    return 0; 
} 

然而兩者+ = 2和< iter.end()似乎是未定義類似的std ::集。想要遍歷一個只訪問每個其他元素(子採樣)的集合似乎是合理的,不是嗎?有沒有另一種方法來做到這一點?

+0

我在iPad上,所以我無法用代碼進行實驗,但我只是想知道是否使用非const迭代器來試用這個代碼? – 2012-02-22 00:46:04

回答

4

與隨機訪問迭代器,你可以簡單地做iter+=n,然後使用< container.end()代替!= container.end()作爲循環結束條件

真正改變步幅,你不能。雖然代碼可能會編譯,但如果迭代器實際上已經超出容器的末尾,它將在運行時顯示未定義的行爲。您不能將迭代器遞增到它指向的範圍的末尾之外。

在任何情況下,你可以寫一個函數模板,以幫助:

template <typename TForwardIt, typename TDifference> 
bool try_advance(TForwardIt& it, 
       TForwardIt const end, 
       TDifference n) 
{ 
    TDifference i(0); 
    while (i < n && it != end) 
    { 
     ++i; 
     ++it; 
    } 

    return i == n; 
} 
+0

如果你把這個調用作爲兩個函數之一,一個是隨機訪問,另一個是服用其他迭代器,對於向量等來說更好。 – 2012-02-22 01:15:27

+0

@詹姆斯麥克奈利斯: 很酷,謝謝。我像這樣使用它:IteratorType iter = v.begin(); while(try_advance(iter,v.end(),2)){std :: cout <<「」<< * iter; } TD差異的想法是什麼?爲什麼不只是:template bool try_advance(TForwardIt&it,TForwardIt const end,const unsigned int n){unsigned int i = 0; while(i 2012-02-22 12:42:42

2

我在iPad上,所以我不能對此進行測試,但嘗試以下

std::advance(iter, 2); 
+1

+1。它確實提升了它的兩個位置......但是,超過@James指出的容器底部的問題依然存在。 – 2012-02-22 00:55:39

+0

啊是的,這絕對是第1部分的解決方案:) – 2012-02-22 00:59:57

+0

可以與邊界/指針檢查結合使用,幾乎沒有優雅的壽命... :) – 2012-02-22 01:05:44