C++ 为什么没有std::erase?

C++ 为什么没有std::erase?,c++,stl,C++,Stl,在阅读STL时,我意识到没有提供std::erase。我真的不知道为什么它不在那里。下面是一个有效的用例 std::vector<int> odd { 1, 3, 5, 3, 9, 11, 5, 17 }; std::sort(odd.begin(), odd.end()); std::erase(std::unique(odd.begin(), odd.end()), odd.end()); std::向量奇数{1,3,5,3,9,11,5,17}; std::sort(奇.be

在阅读STL时,我意识到没有提供
std::erase
。我真的不知道为什么它不在那里。下面是一个有效的用例

std::vector<int> odd { 1, 3, 5, 3, 9, 11, 5, 17 };
std::sort(odd.begin(), odd.end());
std::erase(std::unique(odd.begin(), odd.end()), odd.end());
std::向量奇数{1,3,5,3,9,11,5,17};
std::sort(奇.begin(),奇.end());
std::erase(std::unique(odd.begin()、odd.end()、odd.end());

但它被嵌入到每个容器中。如果性能是原因,那么如果对象是连续的,则可以一次性删除它们。但我想这在帮助模板专门化中是可行的

它将如何工作?它只接受一对迭代器。迭代器不必保留对其容器的引用(向量的迭代器可能只是指针的别名)

那么,算法将如何修改容器本身呢?它需要这种访问


它必须是一个成员函数。

序列和算法之间的粘合剂是迭代器(感谢@Pete Becker在这里为我指出了正确的术语)。它们归结为可应用于多个序列(容器)类型的强大算法所需的最小功能。一个例子就是这样一个片段:

std::vector<int> vec{1, 2, 3, 4};
std::list<int> lst;

std::copy(vec.cbegin(), vec.cend(), std::back_inserter(lst));
std::copy(lst.cbegin(), lst.cend(), std::ostream_iterator<int>(std::cout, " "));
最后一次函数调用实际上可以从容器中删除值为
3
的元素,因为该函数调用中没有隐藏任何信息。相比之下,
*begin
/
*end
(成员)函数家族恰恰做到了这一点:在抽象背后隐藏信息。

于2014年底添加到库基础2 TS的std/experimental int中。这一点最近被选为C++-2a的标准,但即使是github的草案也没有显示出来。我知道gcc、clang和visualstudio支持实验

因此,除了通常的容器外,还应包括以下版本之一:

<experimental/deque>
<experimental/forward_list>
<experimental/list>
<experimental/map>
<experimental/set>
<experimental/string>
<experimental/unordered_map>
<experimental/unordered_set>
<experimental/vector>

这些签名来自:

//
模板
void erase_if(基本字符串&c,谓词pred);
模板
无效擦除(基本字符串和c、常量和值);
// 
模板
无效擦除_if(确定和控制,谓词pred);
模板
无效擦除(数据和c、常数和值);
// 
模板
void erase_if(向量&c,谓词pred);
模板
无效擦除(矢量和c、常量和值);
// 
模板
无效擦除if(转发列表&c,谓词pred);
模板
无效擦除(转发列表和c、常量和值);
// 
模板
无效擦除_if(列表和c,谓词pred);
模板
无效擦除(列表和c、常量和值);
// 
模板
void erase_if(map&c,谓词pred);
模板
void erase_if(多重映射&c,谓词pred);
// 
模板
void erase_if(set&c,谓词pred);
模板
void erase_if(多集&c,谓词pred);
// 
模板
void erase_if(无序映射&c,谓词pred);
模板
void erase_if(无序的多映射&c,谓词pred);
// 
模板
void erase_if(无序集&c,谓词pred);
模板
void erase_if(无序多集&c,谓词pred);

>我想,如果答案是“可能实现但C++决定不做”,这个问题将被关闭为意见基础。注意:java确实提供了通过迭代器从集合中重新收集项目的能力;然而,许多集合是不可变的,所以这个操作并不总是有效的,这导致了不一致的API。迭代器是序列和算法之间的粘合剂。容器是管理序列的一种方法,但它们不是唯一的方法。例如,您可以创建一对遍历输入流的迭代器;很少有人会将输入流称为容器+1无论如何。@PeteBecker谢谢你的提示!我改进了答案。Iirc有一个建议添加(一个重载集)
std::erase_if
,以
boost::remove_erase
的方式,它是std c++17的一部分吗?我认为它仍然是std/17的一部分。我会编辑我的帖子。是的,也许这就是它没有被列在这里的原因——如果通过了,这个提议和更多的提议都是多余的。羞耻。但是,无论如何,+1.0是添加到C++20中的,并在gcc-9、clang-7、最近的可视化研究中实现。
<experimental/deque>
<experimental/forward_list>
<experimental/list>
<experimental/map>
<experimental/set>
<experimental/string>
<experimental/unordered_map>
<experimental/unordered_set>
<experimental/vector>
  // <experimental/string>
  template <class charT, class traits, class A, class Predicate>
    void erase_if(basic_string<charT, traits, A>& c, Predicate pred);
  template <class charT, class traits, class A, class U>
    void erase(basic_string<charT, traits, A>& c, const U& value);

  // <experimental/deque>
  template <class T, class A, class Predicate>
    void erase_if(deque<T, A>& c, Predicate pred);
  template <class T, class A, class U>
    void erase(deque<T, A>& c, const U& value);

  // <experimental/vector>
  template <class T, class A, class Predicate>
    void erase_if(vector<T, A>& c, Predicate pred);
  template <class T, class A, class U>
    void erase(vector<T, A>& c, const U& value);

  // <experimental/forward_list>
  template <class T, class A, class Predicate>
    void erase_if(forward_list<T, A>& c, Predicate pred);
  template <class T, class A, class U>
    void erase(forward_list<T, A>& c, const U& value);

  // <experimental/list>
  template <class T, class A, class Predicate>
    void erase_if(list<T, A>& c, Predicate pred);
  template <class T, class A, class U>
    void erase(list<T, A>& c, const U& value);

  // <experimental/map>
  template <class K, class T, class C, class A, class Predicate>
    void erase_if(map<K, T, C, A>& c, Predicate pred);
  template <class K, class T, class C, class A, class Predicate>
    void erase_if(multimap<K, T, C, A>& c, Predicate pred);

  // <experimental/set>
  template <class K, class C, class A, class Predicate>
    void erase_if(set<K, C, A>& c, Predicate pred);
  template <class K, class C, class A, class Predicate>
    void erase_if(multiset<K, C, A>& c, Predicate pred);

  // <experimental/unordered_map>
  template <class K, class T, class H, class P, class A, class Predicate>
    void erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
  template <class K, class T, class H, class P, class A, class Predicate>
    void erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);

  // <experimental/unordered_set>
  template <class K, class H, class P, class A, class Predicate>
    void erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
  template <class K, class H, class P, class A, class Predicate>
    void erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);