【问题标题】:Transforming an OutputIterator before inserting into a container在插入容器之前转换 OutputIterator
【发布时间】:2020-01-03 20:38:34
【问题描述】:

我有一个函数定义如下:

template <class Iter> Iter generate(Iter);

Iter 应该表现得像一个 OutputIterator,并且返回的迭代器是生成的最后一个元素之后的一个元素(类似于 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);

predicate 和 transform 都是函数。

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

【问题讨论】:

标签: c++ iterator c++17 stdvector


【解决方案1】:

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

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:我做了类似的here 并修改了我的答案here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    相关资源
    最近更新 更多