The code snippet
std::map<int, int> m = { { 1, 2 }, { 3, 4 } };
boost::range::remove_erase_if(
m,
[](const auto& it)
{
return it.first == 1;
});
produces the error
12>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.29.30133
\include\xmemory(1986,1): error C2679: binary '=': no operator found which takes a right-hand operand of type 'std::pair<const int,int>' (or there is no acceptable conversion)
12>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.29.30133\include\utility(269,11): message : could be 'std::pair<const int,int> &std::pair<const int,int>::operator =(volatile const std::pair<const int,int> &)'
12>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.29.30133\include\xmemory(1986,1): message : while trying to match the argument list '(std::pair<const int,int>, std::pair<const int,int>)'
I expected remove_erase_if to remove the first pair {1, 2} from the map.
remove_erase_if behaves as expected when I try it with a vector instead of a map:
std::vector<int> v = { 1, 2, 3, 4 };
boost::range::remove_erase_if(
v,
[](const auto& it)
{
return it == 1;
});
Here v contains {2, 3, 4} after execution. What do I have to adjust, to use remove_erase_if with a map?
In your case boost::remove_erase_if
will do the same as
m.erase(std::remove_if(m.begin(), m.end(), [](const auto& it) { return it.first == 1; }), m.end());
which doesn't work well on std::map
s.
If you can't use C++20 std::erase_if(std::map)
, make your own. When you later upgrade to C++20, you can replace the dnx
namespace with std
in your code that uses dnx::erase_if
.
namespace dnx {
template <class Key, class T, class Compare, class Alloc, class Pred>
typename std::map<Key, T, Compare, Alloc>::size_type erase_if(
std::map<Key, T, Compare, Alloc>& c, Pred pred) {
auto old_size = c.size();
for (auto i = c.begin(), last = c.end(); i != last;) {
if (pred(*i)) {
i = c.erase(i);
} else {
++i;
}
}
return old_size - c.size();
}
} // namespace dnx
int main() {
std::map<int, int> m = {{1, 2}, {3, 4}};
// now works:
dnx::erase_if(m, [](const auto& it) { return it.first == 1; });
}