Given an std::vector<std::unique_ptr<SomeType> >
, is it legal to use
remove_if
on it? In other words, given this code:
std::vector<std::unique_ptr<SomeType> > v;
// fill v, all entries point to a valid instance of SomeType...
v.erase( std::remove_if( v.begin(), v.end(), someCondition ), v.end() );
, am I guaranteed after the erase that all pointers still in v
are
valid. I know that given the intuitive implementation of
std::remove_if
, and given all of the implementations I've looked at,
they will be. I'd like to know if there is anything in the standard
which guarantees it; i.e. that std::remove_if
is not allowed to copy
any of the valid entries without recopying the copy into its final
location.
(I am, of course, supposing that the condition doesn't copy. If the condition has a signature like:
struct Condition
{
bool operator()( std::unique_ptr<SomeType> ptr ) const;
};
, then of course, all of the pointers will be invalid after
remove_if
.)
std::remove : It doesn't actually delete elements from the container but only shunts non-deleted elements forwards on top of deleted elements. vector::erase : Removes from the vector either a single element (position) or a range of elements ([first, last)).
std :: remove Transforms the range [first,last) into a range with all the elements that compare equal to val removed, and returns an iterator to the new end of that range. The function cannot alter the properties of the object containing the range of elements (i.e., it cannot alter the size of an array or a container).
C++ Algorithm remove_if() function is used to eliminate all the elements that satisfy a predicate from a given range [first, last) without disturbing the order of the remaining elements. This function cannot alter the size of the container. It returns an iterator to the new end of the range.
Just like erase()
and resize()
, remove_if()
will move elements (possibly via swapping), so the container elements do not need to be copyable. There's nothing special about unique_ptr
, it's just another move-only type.
As you point out, the predicate should of course take elements by const-reference. Again, just like for any movable type.
25.3.8 in the N3290 speaks about remove function :
Requires: The type of *first shall satisfy the MoveAssignable requirements (Table 22).
and
Note: each element in the range [ret,last), where ret is the returned value, has a valid but unspecified state, because the algorithms can eliminate elements by swapping with or moving from elements that were originally in that range.
This means that it depends on your predicate operator. Since your predicate doesn't create a copy, then the elements are not going to be copied.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With