我想在向量上实现一个跳过某个值的运算符。这就是我写的,我面临的问题是评论:
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 ++必须停在某处(即最后),即使需要跳过向量中的最后一个值。如何实现这一目标?
答案 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"