2017-01-12 118 views
0

我想實現一個運算符而不是跳過某個值的向量。這是我寫的,跟我對着評論的問題:實現跳過迭代器的增量

template<class MyVector> 
struct VectorSkipConstIterator : MyVector::const_iterator { 
    using Base = typename MyVector::const_iterator; 
    using ValueType = typename MyVector::value_type; 

    VectorSkipConstIterator(const ValueType &skip) : Base(), skip_(skip){}; 
    VectorSkipConstIterator(Base it_, const ValueType &skip) 
     : Base(it_), skip_(skip){}; 

    VectorSkipConstIterator &operator++() { 
     do { 
      Base::operator++(); 
     } while (/* have not reached the end */ && this->operator*() == skip_); 
     return *this; 
    } 
private: 
    ValueType skip_; 
}; 

所以,問題是,運營商++已經停止的地方(即,在結束),即使最後的值(S)在矢量需要跳過。這怎麼能實現?

+3

一般來說,你會檢查你是否在客戶端代碼中而不是在迭代器中。從迭代器繼承往往是一個壞的想法™,因爲它可能只是一個指針。 – TartanLlama

回答

1

實現此目的的一種可能方式是簡單地將結束迭代器作爲參數傳遞給VectorSkipConstIterator,並將其保留在字段中。

template<class MyVector> 
struct VectorSkipConstIterator : MyVector::const_iterator { 
    using Base = typename MyVector::const_iterator; 
    using ValueType = typename MyVector::value_type; 

    VectorSkipConstIterator(const ValueType &skip, Base end) 
     : Base(), skip_(skip){}, end_(end) 
    { 
    } 

    VectorSkipConstIterator(Base it_, const ValueType &skip, Base end) 
     : Base(it_), skip_(skip), end_(end) 
    { 
    } 

    VectorSkipConstIterator &operator++() { 
     do { 
      Base::operator++(); 
     } while (*this != end_ && this->operator*() == skip_); 
     return *this; 
    } 
private: 
    ValueType skip_; 
    Base end_; 
}; 

正如TartanLlama在評論中所說的,從一個迭代器繼承並不是一個好主意。考慮從頭開始實現您自己的迭代器類,以滿足RandomAccessIterator概念。


另一個可能(在我看來,更好的)實現的方式,你的願望是使用higher-order function

template <typename TContainer, typename TSkip, typename TF> 
void forEachExcept(TContainer&& c, TSkip&& s, TF&& f) 
{ 
    for(auto&& x : c) 
    { 
     if(x != s) f(x); 
    } 
} 

可以按如下方式使用它:

std::vector<int> v{1,2,5,1,6,2,1}; 

// skip all occurrences of `1` 
forEachExcept(v, 1, [](auto x){ std::cout << x; }); 

// prints "2562"