为什么 Vector 不提供 remove() 成员函数,而列表提供?

why Vector doesn't provide the remove() member function while list provides?

本文关键字:函数 成员 列表 Vector remove 为什么      更新时间:2023-10-16

如果我想从vector中删除所有有值的元素,我会调用remove算法,然后调用vector的擦除成员函数来物理删除它。但在列表的情况下,简单地调用remove成员函数,它将删除所有具有该值的元素。我不确定为什么矢量不能提供删除MF,而列表可以。

对于Exp:我想从向量v.中删除值"4"

vector<int> v;
vector<int> ::iterator Itr;
for (int i=0; i< 6; i++)
   v.push_back(i*2);
v.push_back(4);
v.push_back(8);
v.push_back(4);
v.erase(remove(v.begin(),v.end(),4), v.end()); 

对于列表:

list.remove(4); // will delete all the element which has value 4

问题不在于std::vector为什么不提供操作,而在于std::list为什么提供操作。STL的设计侧重于通过迭代器将容器和算法分离,在所有情况下,如果一个算法可以用迭代器有效地实现,那就是选项。

然而,在某些情况下,使用容器知识可以更有效地实现特定操作。这就是从容器中移除元素的情况。使用remove-erase习惯用法的成本在容器的大小上是线性的(不能减少太多),但这掩盖了一个事实,即在最坏的情况下,除了一个操作外,所有这些操作都是对象的副本(唯一匹配的元素是第一个),这些副本可能代表相当大的隐藏成本。

通过将操作实现为std::list中的一种方法,操作的复杂性仍然是线性的,但移除的每个元素的相关成本非常低,几个指针复制和释放内存中的节点。同时,作为列表一部分的实现可以提供更强的保证:未擦除元素的指针、引用和迭代器不会在操作中失效。

在特定容器中实现的算法的另一个示例是std::list::sort,它使用比std::sort效率低但不需要随机访问迭代器的mergesort

因此,基本上,算法是用迭代器实现的自由函数,除非有充分的理由在具体容器中提供特定的实现。

我认为理由是std::list提供了一种非常有效的remove方法(如果实现为双链接列表,它只调整指向元素的指针并释放其存储),而std::vector的元素移除相对较慢。

remove+erase技巧是适用于所有提供所需迭代器类型的容器类型的标准方法。据推测,STL的设计者想要指出这种差异。他们本可以选择给所有容器一个remove方法,这将是所有容器的remove+erase,除了那些知道更好方法的容器,但他们没有。

乍一看,这似乎违反了泛型代码的思想,但我不认为它真的违反了。拥有一个易于访问的简单通用remove,可以很容易地编写对所有容器类型都能很好编译的通用代码,但最终,在10种情况中有9种情况下运行速度非常慢,而在第10种情况下则运行速度极快的通用代码并不是真正的通用代码

与一般CCD_ 15相比,在CCD_。

从向量中删除元素比从列表中删除元素慢得多:它(平均而言)与向量的大小成比例,而对列表的操作是在恒定时间内执行的。

标准库的设计者根据"看起来容易的东西应该(在计算上)容易"的原则,决定不包括这个功能。

我不确定我是否同意这种哲学,但它被认为是C++的设计目标。

因为从列表中删除项很便宜,而在向量上删除项则很昂贵-必须移动以下所有元素,即复制/移动。

我认为这是由于效率的原因,从向量中删除随机元素的速度比从列表中删除慢。这可能意味着在这种情况下需要更多的类型,但至少在界面中很明显,如果您需要经常这样做,std::vector不是最好的数据结构。