簡體   English   中英

擦除-刪除習語如何與范圍/受限算法一起使用?

[英]How does the erase-remove idiom work with ranges/constrained algorithms?

我正在嘗試將 c++20 約束算法用於擦除刪除習語:

std::vector<int> v;
v.erase(std::unique(std::begin(v), std::end(v)), std::end(v));

但是當我做一個簡單的轉換時:

v.erase(std::ranges::unique(v), std::end(v));

我收到一個錯誤,指出要erase的參數不匹配:

error: no matching function for call to 'std::vector<int>::erase(std::ranges::borrowed_subrange_t<std::vector<int>&>, std::vector<int>::iterator)'

如果第二個參數是std::ranges::end(v)則會產生類似的錯誤。

我怎樣才能讓它發揮作用?


該問題最初使用remove而不是unique ,但所有容器都有一個重載的std::erase ,這使得該特定用例的動機降低。

std::ranges::unique (和std::ranges::remove )返回從第一個移除元素到容器末尾的子范圍,因此您需要在傳遞給std::vector::erase之前使用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));

它不起作用,因為std::ranges::remove()返回的不是迭代器而是范圍。 但即使您嘗試v.erase(std::ranges::remove(...))它也不會工作,因為 vector 沒有將 range 作為參數的erase()重載。

相反,看看std::erase() (在<vector>定義)。 您需要的可能只是std::erase(v, 42)

另一種選擇是分解std::ranges::remove / unique返回的子std::ranges::remove ,並使用這些迭代器:

auto [Beg, End] = std::ranges::remove(v, 42);
v.erase(Beg, End);

在 C++20 中, std::ranges::unique/remove返回一個std::ranges::subrange ,它包含我們通常想要擦除的子范圍( begin()指向第一個被刪除的元素,而end()指向容器的end() ),所以我認為 C++20 中正確的擦除-刪除習慣用法是:

std::vector<int> v;
v.resize(v.size() - std::ranges::unique(v).size());
v.resize(v.size() - std::ranges::remove(v, 42).size());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM