62 lines
1.8 KiB
Plaintext
62 lines
1.8 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Removing elements with a specific value or that follow a given predicate from a container is a common task. Before {cpp}20, this was not straightforward. The way to do it had to depend on the type of your container.
|
|
|
|
|
|
For sequence containers, you would end up following what is called the _erase-remove idiom_:
|
|
|
|
* Call ``++std::remove++`` or ``++std::remove_if++`` with, as parameters, the container and the criterion to fulfill
|
|
* Call the container member function ``++erase++`` on the result
|
|
|
|
For associative containers, you would have no other option than looping through all the elements by hand.
|
|
|
|
|
|
However, {cpp}20 introduced two new methods: ``++std::erase++`` (for sequence containers only) and ``++std::erase_if++`` which erase all elements equal to a value or that satisfy a given predicate.
|
|
|
|
|
|
This rule raises an issue when ``++std::erase++`` or ``++std::erase_if++`` could be used to simplify the code.
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,cpp]
|
|
----
|
|
void removeZeros(std::vector<int> &v) {
|
|
v.erase(std::remove(v.begin(), v.end(), 0), v.end()); // Noncompliant
|
|
}
|
|
|
|
void removeOddNumbers(std::vector<int> &v) {
|
|
v.erase(std::remove_if(v.begin(), v.end(), [](auto i) { return i%2 == 0; }), v.end()); // Noncompliant
|
|
}
|
|
|
|
void removeOddNumbers(std::unordered_map<std::string, int> &m) {
|
|
auto it = m.begin();
|
|
while (it != m.end()) { // Noncompliant
|
|
if (it->second % 2 == 0) {
|
|
it = m.erase(it);
|
|
} else {
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
=== Compliant solution
|
|
|
|
[source,cpp]
|
|
----
|
|
void removeZeros(std::vector<int> &v) {
|
|
std::erase(v, 0);
|
|
}
|
|
|
|
void removeOddNumbers(std::vector<int> &v) {
|
|
std::erase_if(v, [](auto i) { return i%2 == 0; });
|
|
}
|
|
|
|
void removeOddNumbers(std::unordered_map<std::string, int> &m) {
|
|
std::erase_if(m, [](auto item) { return item.second % 2 == 0; });
|
|
}
|
|
----
|
|
|