实现跳过迭代器的增量

时间:2017-01-12 09:25:46

标签: c++ iterator

我想在向量上实现一个跳过某个值的运算符。这就是我写的,我面临的问题是评论:

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_;
};

所以,问题是operator ++必须停在某处(即最后),即使需要跳过向量中的最后一个值。如何实现这一目标?

1 个答案:

答案 0 :(得分:1)

实现此目的的一种可能方法是将 end iterator 作为参数传递给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"