假设我有std::vector<std::pair<int,Direction>>
。
我正在尝试使用erase-remove_if惯用法从向量中删除对。
stopPoints.erase(std::remove_if(stopPoints.begin(),
stopPoints.end(),
[&](const stopPointPair stopPoint)-> bool { return stopPoint.first == 4; }));
我想删除所有将.first值设置为4的对。
在我的例子中,我有成对:
- 4, Up
- 4, Down
- 2, Up
- 6, Up
然而,在我执行erase-remove_if后,我留下了:
- 2, Up
- 6, Up
- 6, Up
我在这里做错了什么?
答案 0 :(得分:15)
正确的代码是:
stopPoints.erase(std::remove_if(stopPoints.begin(),
stopPoints.end(),
[&](const stopPointPair stopPoint)-> bool
{ return stopPoint.first == 4; }),
stopPoints.end());
您需要删除从std::remove_if
返回到迭代器的范围,而不仅仅是单个元素。
&#34;为什么&#34;
std::remove_if
在向量内部交换元素,以便将与谓词不匹配的所有元素放到容器的开头。
然后返回指向第一个谓词匹配元素的迭代器。
std::vector::erase
需要擦除从返回的迭代器开始到向量的范围,以便删除与谓词匹配的所有元素强>
答案 1 :(得分:7)
方法std::vector::erase
有两个重载:
iterator erase( const_iterator pos );
iterator erase( const_iterator first, const_iterator last );
第一个仅删除pos
处的元素,而第二个删除范围[first, last)
。
由于您在调用中忘记了last
迭代器,因此第一个版本是通过重载决策选择的,并且您只删除了std::remove_if
移动到末尾的第一个版本。你需要这样做:
stopPoints.erase(std::remove_if(stopPoints.begin(),
stopPoints.end(),
[&](const stopPointPair stopPoint)-> bool { return stopPoint.first == 4; }),
stopPoints.end());
erase-remove 成语的工作方式如下:假设您有一个向量{2, 4, 3, 6, 4}
,并且要删除4
:
std::vector<int> vec{2, 4, 3, 6, 4};
auto it = std::remove(vec.begin(), vec.end(), 4);
通过将&#34;删除&#34;将矢量转换为{2, 3, 6, A, B}
。最后的值(末尾的值A
和B
未指定(就好像值已移动),这就是为什么你有6
个你的例子)并将迭代器返回A
(第一个&#34;删除&#34;值)。
如果你这样做:
vec.erase(it)
选择std::vector::erase
的第一个重载,您只删除it
处的值,即A
并获取{2, 3, 6, B}
。
添加第二个参数:
vec.erase(it, vec.end())
选择第二个重载,并删除it
和vec.end()
之间的值,以便删除A
和B
。