Move iterators for containers?

后端 未结 2 442
醉话见心
醉话见心 2021-01-04 23:58

C++98 containers defined two kinds of iterator, ::iterators and ::const_iterators. Generally, like this:

struct vec{
   iterator be         


        
2条回答
  •  太阳男子
    2021-01-05 00:49

    STL containers are designed to be used in conjunction with STL algorithms. The generic algorithms currently found in the STL deal with iterators, but your template function transport_first:

    template
    void transport_first(Container&& c, std::vector& v){
        v.emplace_back(*std::forward(c).begin());
    }
    

    consists of container-based code, i.e.: it operates on containers rather than on iterators. We may be able to find such container-based algorithms as part of the STL as of C++20 thanks to concepts.

    The "STL-like approach" to a generic transport_first algorithm would actually be:

    template
    void transport_first(InIt src, OutIt dst) {
        *dst = *src;
    }
    

    Following this approach (i.e.: iterators instead of containers), when it comes to generic code, whether to use move_iterator or not can be simply determined at the "topmost" generic algorithm, since the passed iterators are copied further (i.e.: being passed by value into the "underlying" algorithms).

    In addition, unlike the iterator-based transport_first above, the STL is full of iterator pair-based algorithms (e.g.: std::copy) to implement ranges. This interface makes overloading those container member functions on rvalues little attractive, because as already stated in this other answer, those overloaded member functions will be called, among others, on unnamed (non-const) container objects, and unnamed container objects are limited to be used in a single expression, hindering the creation of an iterator pair by calling both begin() and end() member functions on the same container object.


    What would really make sense for containers, is to have fresh new member functions for returning the corresponding move_iterator objects:

    move_iterator Container::mbegin();
    move_iterator Container::mend();
    

    This would be just a shortcut for calling std::make_move_iterator with the value returned by the member functions returning a iterator. The member function mbegin() would be used in the iterator-based transport_first as:

    transport_first(coll.mbegin(), std::back_inserter(vec));
    

    The corresponding function templates std::mbegin() and std::mend() would also make sense:

    transport_first(std::mbegin(coll), std::back_inserter(vec));
    

提交回复
热议问题