I'm trying to use a c++20 constrained algorithm for the erase-remove idiom:
std::vector<int> v;
v.erase(std::unique(std::begin(v), std::end(v)), std::end(v));
but when I do a simple transformation:
v.erase(std::ranges::unique(v), std::end(v));
I get an error that the arguments to erase
don't match:
error: no matching function for call to 'std::vector<int>::erase(std::ranges::borrowed_subrange_t<std::vector<int>&>, std::vector<int>::iterator)'
A similar error is produced if the second argument is std::ranges::end(v)
.
How can I get this to work?
The question originally used remove
instead of unique
, but there is an overloaded std::erase
for all containers that makes that particular use case less motivating.
std::ranges::unique
(and std::ranges::remove
) returns a sub range from the first removed element to the end of the container so you need to use std::begin
before passing to std::vector::erase
:
v.erase(std::ranges::begin(std::ranges::remove(v, 42)), std::end(v));
v.erase(std::ranges::begin(std::ranges::unique(v)), std::end(v));
It doesn't work since std::ranges::remove()
returns not iterator but range. But even if you try v.erase(std::ranges::remove(...))
it will not work, because vector does not have erase()
overload which takes range as parameter.
Instead, take a look at std::erase()
(defined in <vector>
). What you need is probably just std::erase(v, 42)
.
Another option would be decomposing the subrange returned by std::ranges::remove
/ unique
, and use those iterators:
auto [Beg, End] = std::ranges::remove(v, 42);
v.erase(Beg, End);
In C++20, std::ranges::unique/remove
returns a std::ranges::subrange
which contains the sub-range that we want to erase usually ( begin()
point to the first removed element, and end()
point to the containers's end()
), so I think the proper erase-remove idiom in C++20 is:
std::vector<int> v;
v.resize(v.size() - std::ranges::unique(v).size());
v.resize(v.size() - std::ranges::remove(v, 42).size());
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.