问题
It is commonly understood that a good way to fully delete desired items from a std::vector
is the erase-remove idiom.
As noted in the above link (as of the date of this posting), in code the erase-remove idiom looks like this:
int main()
{
// initialises a vector that holds the numbers from 0-9.
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// erase-remove idiom to completely eliminate the desired items from the vector
v.erase( std::remove( std::begin(v), std::end(v), 5 ), std::end(v) );
}
I would like to know whether a resize-remove
idiom is equivalent in terms of functionality and performance to the erase-remove
idiom. Or, perhaps I am missing something obvious?
Is the following resize-remove
idiom equivalent to the above erase-remove
idiom?
int main()
{
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// Is this "resize-remove" approach equivalent to the "erase-remove" idiom?
v.resize( std::remove( std::begin(v), std::end(v), 5 ) - v.begin() );
}
回答1:
In my opinion, there are two reasons:
std::remove
algorithm requires only Forward Iterator, but-
op requires Random Access Iterator.The result of
std::remove
means "the new end of container". Logically, we should erase [ "the new end of container" , "the old end of container" ).
回答2:
It is equivalent for std::vector, but not for std::list or other containers. Not sure if subtracting iterators is even possible for std::list, and even if it is, it is a O(N) operation.
回答3:
It shouldn't make any difference; resize
is defined in terms
of insert
and erase
. But it is usually preferable to use the
standard idiom, so that it can easily be recognized. And of
course, the erase-remove idiom will work with any sequence
container, and not just those which support resize
. (All of
the standard containers do seem to support resize
, but it
doesn't seem to be a requirement. So it might not be available
on user defined containers, even though they support all
required operations.)
In terms of performance: the resize
must do one additional
test, to determine whether it is erasing or inserting, but
I can't imagine this making a significant impact.
回答4:
I think erase
in erase(first,last)
guarantees that no elements before first
are accessed or modified, while resize
only guarantees this when no reallocation happens because of the resize.
Edit: as pointed out by others, such a reallocation will never happen, so there's no difference
来源:https://stackoverflow.com/questions/22860119/stl-erase-remove-idiom-why-not-resize-remove