簡體   English   中英

C++ std::set::erase 與 std::remove_if

[英]C++ std::set::erase with std::remove_if

此代碼具有 Visual Studio error C3892 如果我將std::set更改為std::vector - 它可以工作。

std::set<int> a;
a.erase(std::remove_if(a.begin(), a.end(), [](int item)
{
    return item == 10;
}), a.end());

怎么了? 為什么我不能將std::remove_ifstd::set

您不能將std::remove_if()與具有const部分的序列一起使用。 std::set<T>元素序列由T const對象組成。 我們實際上就在昨天在標准 C++ 委員會上討論了這個問題,並且有一些支持創建專門處理容器中的erase()對象的算法。 它看起來像這樣(另見N4009 ):

template <class T, class Comp, class Alloc, class Predicate>
void discard_if(std::set<T, Comp, Alloc>& c, Predicate pred) {
    for (auto it{c.begin()}, end{c.end()}; it != end; ) {
        if (pred(*it)) {
            it = c.erase(it);
        }
        else {
            ++it;
        }
    }
}

(它可能實際上委托一個算法調度到上面的邏輯,因為相同的邏輯對於其他基於節點的容器是相同的)。

對於您的特定用途,您可以使用

a.erase(10);

但這僅適用於您想刪除鍵而上述算法適用於任意謂詞的情況。 另一方面, a.erase(10)可以利用std::set<int>的結構並且將是 O(log N) 而算法是 O(N) (其​​中N == s.size() )。

std::remove_if重新std::remove_if元素,因此它不能與std::set一起使用。 但是你可以使用std::set::erase

std::set<int> a;
a.erase(10);

從 C++20 開始,您可以將std::erase_if用於具有erase()方法的容器,正如Kühl 所解釋的那樣。 請注意,這也包括std::vector ,因為它具有擦除方法。 不再鏈接a.erase(std::remove_if(... :)

暫無
暫無

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

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