在插入容器之前转换输出迭代器

Transforming an OutputIterator before inserting into a container

本文关键字:转换 输出 迭代器 插入      更新时间:2023-10-16

我有一个函数定义如下:

template <class Iter> Iter generate(Iter);

其中 Iter 的行为应该像输出迭代器一样,返回的迭代器是生成的最后一个元素之后的一个元素(类似于std::transform的第三个参数(

我想调用此函数,对生成的每个项目应用谓词,然后将其余元素转换为其他类型。我知道我可以按如下方式执行此操作:

std::vector<some_type> generated_raw;
generate(std::back_inserter(generated_raw));
generated_raw.erase(std::remove_if(generated_raw.begin(), generated_raw.end(), predicate));
std::vector<other_type> generated;
std::transform(generated_raw.begin(), generated_raw.end(), std::back_inserter(generated), transform);

其中谓词和变换都是函数。

但是,这是低效的,因为它涉及一个中间容器,其中存储了每个生成的元素 - 即使是那些稍后将被擦除/remove_if调用拒绝的元素。有没有更好的方法?

这样的事情应该可以解决问题:

template<class Iter, class Pred>
struct PredicatedIter {
Iter it;
Pred pr;
PredicatedIter& operator=(const typename Iter::Container::value_type &v) {
if(pr(v)) {
it = v;
}
return *this;
}
PredicatedIter& operator=(typename Iter::Container::value_type &&v) {
if(pr(v)) {
it = std::move(v);
}
return *this;
}
// no-ops as in back_insert_iterator    
PredicatedIter& operator++() {
return *this;
}
PredicatedIter& operator++(int) {
return *this;
}
PredicatedIter& operator*() {
return *this;
}
};

PS:我在这里做了类似的事情,并在这里重新设计了我的答案。