Assign part of a vector to itself using std::vector::assign()

前端 未结 2 754
借酒劲吻你
借酒劲吻你 2021-01-21 02:38

Let\'s say I have a vector(v1) of size 10. Now I want to only keep parts of the elements, using:
v1.assign(v1.begin() + 2, v1.begin() + 6);

What I\'

相关标签:
2条回答
  • 2021-01-21 03:05

    From the C++11 Standard:

    23.3.6.2 vector constructors, copy, and assignment

    template <class InputIterator>
    void assign(InputIterator first, InputIterator last);
    

    11 Effects:

    erase(begin(), end());
    insert(begin(), first, last);
    

    In other words, don't use:

    v1.assign(v1.begin() + 2, v1.begin() + 6);
    

    By the time insert is called, first will be an invalid iterator.

    0 讨论(0)
  • 2021-01-21 03:11

    Per the C++14 standard Table 100 — Sequence container requirements (in addition to container)

    The expression a.assign(i,j) has a pre-condition that i and j are not iterators into a. Since

    v1.assign(v1.begin() + 2, v1.begin() + 6);
    

    Uses iterators that are iterators into v1 so you have violated that pre-condition

    If you want to reset the vector to contain a subrange then you can copy those elements into a temporary vector and then assign that temporary vector back to main vector. This should be a move operation(C++11 and above) so no additional copies are made.

    vector_name = std::vector<type_used_for_vector_name>(vector_name.begin() + 2, vector_name.begin() + 6);
    

    As pointed out in the comments from Benjamin Lindley and Barry we can use std::copy and move iterators like

    std::copy(std::make_move_iterator(v.begin() + 2), std::make_move_iterator(v.begin() + 6), 
              std::make_move_iterator(v.begin()));
    
    0 讨论(0)
提交回复
热议问题