cig*_*ien 18 c++ c++20 std-ranges
我正在尝试将 c++20 约束算法用于擦除删除习语:
std::vector<int> v;
v.erase(std::unique(std::begin(v), std::end(v)), std::end(v));
Run Code Online (Sandbox Code Playgroud)
但是当我做一个简单的转换时:
v.erase(std::ranges::unique(v), std::end(v));
Run Code Online (Sandbox Code Playgroud)
我收到一个错误,参数erase不匹配:
error: no matching function for call to 'std::vector<int>::erase(std::ranges::borrowed_subrange_t<std::vector<int>&>, std::vector<int>::iterator)'
Run Code Online (Sandbox Code Playgroud)
如果第二个参数是 ,则会产生类似的错误std::ranges::end(v)。
我怎样才能让它发挥作用?
该问题最初使用remove而不是unique,但是std::erase所有容器都过载了,这使得该特定用例的动机降低。
Ala*_*les 12
std::ranges::unique(和std::ranges::remove) 返回从第一个删除元素到容器末尾的子范围,因此您需要std::begin在传递给之前使用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));
Run Code Online (Sandbox Code Playgroud)
另一种选择是分解std::ranges::remove/返回的子范围unique,并使用这些迭代器:
auto [Beg, End] = std::ranges::remove(v, 42);
v.erase(Beg, End);
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为std::ranges::remove()返回的不是迭代器而是范围。但即使你尝试v.erase(std::ranges::remove(...))它也不会起作用,因为向量没有erase()以范围作为参数的重载。
相反,请查看std::erase()(在 中定义<vector>)。你需要的可能只是std::erase(v, 42).