Vector :: erase and reverse_iterator

I have a set of elements in std :: vector that are sorted in descending order starting from the first element. I have to use a vector because I need to have elements in a continuous piece of memory. And I have a collection containing many instances of vectors with the described characteristics (always sorted in descending order).

Now, sometimes, when I find that I have too many elements in a larger collection (the one that stores these vectors), I drop the smallest elements from these vectors in some way similar to this pseudocode:

grand_collection: collection that holds these vectors
T: type argument of my vector
C: the type that is a member of T, that participates in the < comparison (this is what sorts data before they hit any of the vectors).

std::map<C, std::pair<T::const_reverse_iterator, std::vector<T>&>> what_to_delete;
iterate(it = grand_collection.begin() -> grand_collection.end())
{
     iterate(vect_rit = it->rbegin() -> it->rend())
     {
         // ...
          what_to_delete <- (vect_rit->C, pair(vect_rit, *it))
          if (what_to_delete.size() > threshold)
               what_to_delete.erase(what_to_delete.begin());
         // ...  
     }
}

, , what_to_delete , , ( ). , , , , what_to_delete[0 - n] , n - m , n, m > 0.

_ . ++ 11 §24.4.1/1:

_ & * (reverse_iterator (i)) == & * (i-1)

, a vect_rit :

vector.erase(--vect_rit.base());

, ++ 11 §23.3.6.5/3:

( ); : Invalidates .

reverse_iterators? (vector[0]) vect_rit , ? reverse_iterator rbegin() ( vector[vector.size()]) -, 0-, ?

Edit:

, reverse_iterator rbegin() . , , , . ( const_iterator) what_to_delete .

, , , _ ? ?

!

+5
3

, reverse_iterator:

_ & * (reverse_iterator (i)) == & * (i-1)

, reverse_iterator "" (reverse_iterator::current). " ", , reverse_iterator - , current. reverse_iterator . reverse_iterator::base().

--vect_rit.base(), --current, current .

--vect_rit.base() . ( vector), vect_rit.base() rvalue ( ++ 11), , l. . " 28: , reverse_iterator iterator" " STL" . ( " 3" http://www.drdobbs.com/three-guidelines-for-effective-iterator/184401406).

(++vect_rit).base(), . , : vect_rit.base() - 1

, vect_rit , vect_rit.current .

, vector::erase() , , . " " vect_rit:

vect_rit = vector_type::reverse_iterator( vector.erase(vect_rit.base() - 1));
+2

( , ): §24.5.1.1:

namespace std {
    template <class Iterator>
    class reverse_iterator ...
    {
        ...
            Iterator base() const; // explicit
        ...
        protected:
            Iterator current;
        ...
    };
}

§24.5.1.3.3:

Iterator base() const; // explicit
    Returns: current.

, , , - vector , reverse_iterator, reverse_iterator .

, , : , , , vector.erase(--vector_rit.base()) , reverse_iterator "" , vector.erase(...) - undefined.

, , , :

std::vector<T> v=...;
...
// it_1 and it_2 are contiguous
std::vector<T>::reverse_iterator it_1=v.rend();
std::vector<T>::reverse_iterator it_2=it_1;
--it_2;

// Erase everything after it_1 pointee:

// convert from reverse_iterator to iterator
std::vector<T>::iterator tmp_it=it_1.base();

// but that points one too far in, so decrement;
--tmp_it;

// of course, now tmp_it points at it_2 base:
assert(tmp_it == it_2.base());

// perform erasure
v.erase(tmp_it);  // invalidates all iterators pointing at or past *tmp_it
                  // (like, say it_2.base()...)

// now delete it_2 pointee:
std::vector<T>::iterator tmp_it_2=it_2.base(); // note, invalid iterator!

// undefined behavior:
--tmp_it_2;
v.erase(tmp_it_2);

, : iterator , ( ), . / ( Dinkumware STL - ?) .

+3

reverse_iterator, iterator, . , , ( ) . - . + - w.r.t. ( ++ --, > < ..).

, .

, :

.

Links do not have a built-in sense of direction. Therefore, the language clearly indicates the intrinsic meaning of the direction of the container. Positions after the erase point are positions with higher rates. Therefore, the direction of the iterator does not matter here.

0
source

All Articles