Suppose you want to remove a single element from a vector by value. What is the difference between remove-erase:
vector<int> v;
// add some values
vector<int>::iterator it = remove(v.begin(), v.end(), 5);
v.erase(it);
And find-erase
vector<int> v;
// add some values
vector<int>::iterator it = find(v.begin(), v.end(), 5);
if(it != v.end())
{
v.erase(it);
}
What's the difference between delete and remove? This is a simple definition: Remove and Delete are defined quite similarly, but the main difference between them is that delete means erase (i.e. rendered nonexistent or unrecoverable), while remove denotes take away and set aside (but kept in existence).
Therefore, erase() is something you can do to an element in a container, remove() is something you can do to a range as it re-arranges that range but doesn't erase anything from the range..
When you erase something, you eliminate or delete it, often by physically wiping it out. It's easy to erase chalk from a blackboard, but not so easy to erase graffiti from the side of a building.
Erase is a term that describe the process of removing or deleting data. In most situations, when data is deleted or erased from the hard drive, it's marked as deleted yet remains on the hard drive until it's overwritten by something else.
Your remove-erase code is not correct. The remove-erase idiom looks like this:
vector<int>::iterator it = remove(v.begin(), v.end(), 5);
v.erase(it, v.end());
In that case, it has the effect of erasing all values equal to 5 but it minimises the amount of copying required to achieve that.
Your find-erase code removes only the first value equal to 5, so it does what you want.
Your remove-erase code moves all the values not equal to 5 to the front of the vector (that's what std::remove
does), erases one of the remaining elements of the vector, and leaves any remaining elements after that with unspecified values (which is also what remove
does). It has undefined behavior if the vector doesn't contain a 5
to begin with, because remove
would return v.end()
in that case.
So, if you only want to erase a single element of several equal to 5 then std::remove
is no use to you because it doesn't preserve the (other) 5s. If you want to move the non-5 values to the start and the 5 values to the end, before removing the first of the 5s, then you could in fact do that with std::partition
just not with std::remove
:
auto it = partition(v.begin(), v.end(), [](int i) { return i != 5; });
if (it != v.end()) v.erase(it);
Although, since one 5 is as good as another you get the same result by erasing the last of the 5s rather than the first, and it's more efficient when there's more than one of them:
auto it = partition(v.begin(), v.end(), [](int i) { return i != 5; });
if (it != v.end()) v.pop_back();
If you can somehow be sure that the vector initially contains exactly one element equal to 5 (no more or less), then your two bits of code do the same thing. And in that case you wouldn't need the test for it != v.end()
in the find-erase code, you would know it isn't equal. You could just do v.erase(find(v.begin(), v.end(), 5))
.
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