using std::transform the final vector remains empty

送分小仙女□ 提交于 2020-01-16 16:58:45

问题


I am not using std::transform often, however I found it very useful and I am starting replacing some for loops with this algorithm.

What is wrong here? I want to keep all the elements of the vector vec that have code > 100. I would expect to have a new std::vector with 3 elements: 133, 144 and 155. But after the algorithm the size is 0. What is wrong?

 TEST_CASE("testing trasf1", "[tras1]") {

    std::vector<Test2> vec {
            {1,1},
            {3,3},
            {11,11},
            {12,12},
            {133,133},
            {19,19},
            {21,21},
            {22,22},
            {23,23},
            {144,144},
            {155,155}

    };

    std::vector<uint32_t> final_v {};
    final_v.reserve(vec.size());

    transform(begin(vec), end(vec), begin(final_v), [] (const Test2& elem) {
        if ( elem.getCode() > 100)
            return elem.getCode();
    });

    //REQUIRE(final.size() == 3);

    cout << final_v.size() << endl;

    for (const auto i : final_v) {
        cout << i << endl;
    }

}

回答1:


transform doesn't insert elements into the output sequence, it just writes to the *iter and increments the iterator.

If you want to insert to the sequence, use std::back_inserter(final) as the output iterator.

Alternatively, call final.resize(vec.size()) first, to set the output vector to the correct size. Note that this will intialize the vector elements to zero, so for large vectors will incur a noticeable time overhead.




回答2:


Doing filter and transform in one operation:


template<class Container>
struct optional_inserter_iterator: std::back_insert_iterator //convenience
{
    using std::back_insert_iterator::*;
    optional_inserter_iterator(Container &c) : std::back_insert_iterator(c)
    {}

    optional_inserter_iterator & operator=(std::optional<Container::value_type> &&opt)
    {
        if(opt)
            std::back_insert_iterator::operator=(*std::move(opt))
        return *this;
    }
}

Use this in transform and let your lambda return an optional

(untested)

EDIT: There are some reasons not to inherit from std::back_insert_iterator. If someone is interested in a really correct version, I can do one.



来源:https://stackoverflow.com/questions/59068682/using-stdtransform-the-final-vector-remains-empty

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!