如果我想用vector中的值删除所有元素,我调用remove algorithm 然后调用vector的erase成员函数来物理删除它。 但是在list的情况下,简单的调用删除成员函数,它将删除具有该值的所有元素。 我不确定为什么vector在列表执行时不提供删除MF。
对于Exp:我想从vector 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
答案 0 :(得分:9)
问题不是为什么std::vector
不提供操作,而是为什么std::list
提供它。 STL的设计侧重于通过迭代器分离容器和算法,并且在迭代器方面可以有效地实现算法的所有情况下,这是可选的。
通过将操作实现为std::list
中的方法,操作的复杂性仍然是线性的,但删除的每个元素的相关成本非常低,一对指针复制和释放内存中的节点。同时,作为列表一部分的实现可以提供更强的保证:未擦除元素的指针,引用和迭代器不会在操作中失效。
在特定容器中实现的算法的另一个示例是std::list::sort
,它使用mergesort
效率低于std::sort
但不需要随机访问迭代器。
基本上,算法是用迭代器实现的自由函数,除非有充分理由在具体容器中提供特定的实现。
答案 1 :(得分:4)
我认为理由是std::list
提供了一种非常有效的remove
方法(如果实现为双向链接列表,它只调整指向元素的指针并释放其存储空间),同时删除元素std::vector
速度相对较慢。
remove+erase
技巧是适用于提供所需迭代器类型的所有容器类型的标准方法。据推测,STL的设计师想要指出这种差异。他们可以选择为所有容器提供remove
方法,除了那些知道更好方法的容器外,所有容器都是remove+erase
,但他们没有。
这似乎乍一看违反了通用代码的想法,但我认为它确实没有。拥有一个易于访问的简单通用remove
,可以很容易地编写可以编译所有容器类型的通用代码,但最后通用代码在10个案例中的9个中运行速度非常慢,而且速度非常快第十个不是真正的泛型,它只是看起来如此。
可以在std::map::find
与通用std::find
找到相同的模式。
答案 2 :(得分:3)
从向量中删除元素比对列表这样做要慢得多:它(平均)与向量的大小成比例,而列表上的操作是在恒定时间内执行的。
标准库的设计者决定不将此功能包含在“看起来容易(易于计算)”的原则中。
我不确定我是否同意这一理念,但它被认为是C ++的设计目标。
答案 3 :(得分:1)
因为从列表中删除项目很便宜,而在向量上执行此操作非常昂贵 - 所有后续元素都必须移位,即复制/移动。
答案 4 :(得分:0)
我想,由于效率问题,从矢量中删除随机元素比从列表中删除更慢。对于这样的情况,这可能意味着更多的打字,但至少在界面中显而易见的是std::vector
不是最好的数据结构,如果你需要经常这样做。