Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a back_inserter variant that takes advantage of move?

In generic code I was trying to tell an output iterator (in practice a std::back_inserter_iterator to move a range of elements. To my surprise it looked as if elements were moved in a move-to-back_inserter operation.

#include<algorithm> // move
#include<iterator> // back_inserter
#include<vector>
int main(){
    std::vector<std::vector<double> > v(10, std::vector<double>(100));
    std::vector<std::vector<double> > w;

    assert( not v[0].empty() and w.size() == 0 );
    std::copy(v.begin(), v.end(), std::back_inserter(w));
    assert( not v[0].empty() and w.size() == 10 );

    std::move(v.begin(), v.end(), std::back_inserter(w));
    assert( v[0].empty() and w.size() == 20 ); // were v elements moved to w?
}

However I don't think it is possible that elements of v were really moved to w, because after all back_inserter will do a push_back which implies a copy to w.

It seems more likely that in the std::move case, v elements were moved to a temporary and only then copied into w.

Is that correct? Is there a std::back_inserter really moving somehow?

Is there already a variant of std::back_inserter that takes advantage of move/emplace? Something like an std::back_emplacer?

like image 649
alfC Avatar asked Jan 22 '19 08:01

alfC


1 Answers

std::back_inserter() is a convenience function template for creating an std::back_insert_iterator object.

The class std::back_insert_iterator has already operator= overloaded for taking rvalue reference types, i.e.:

back_insert_iterator<Container>& operator=(typename Container::value_type&& value);

Therefore, std::back_insert_iterator is already prepared to take advantage of move semantics.

like image 50
ネロク・ゴ Avatar answered Nov 14 '22 22:11

ネロク・ゴ