C++ 迭代器范围擦除元素

C++ 迭代器范围擦除元素,c++,algorithm,boost,stl,iterator,C++,Algorithm,Boost,Stl,Iterator,是否可以从迭代器_范围中删除元素 类似这样的内容(不幸的是,此代码不起作用): void test\u erase(my\u it,my\u it end){ 迭代器范围r(it,end); for(;it迭代器范围只不过是一对底层迭代器 因此,是否可以在不使迭代器失效的情况下从底层容器中删除,取决于底层容器 一般来说,std::list会支持这一点,但不支持,例如std::vector虽然remove\u如果在一元谓词上操作,则在任何其他n参数谓词上扩展它并不困难 例如,remove with

是否可以从迭代器_范围中删除元素

类似这样的内容(不幸的是,此代码不起作用):

void test\u erase(my\u it,my\u it end){
迭代器范围r(it,end);

for(;it迭代器范围只不过是一对底层迭代器

因此,是否可以在不使迭代器失效的情况下从底层容器中删除,取决于底层容器


一般来说,
std::list
会支持这一点,但不支持,例如
std::vector

虽然remove\u如果在一元谓词上操作,则在任何其他n参数谓词上扩展它并不困难

例如,remove with binary谓词可以这样编写:

template<class ForwardIt, class BinaryPredicate>
ForwardIt removeif(ForwardIt first, ForwardIt last, BinaryPredicate p) {

    ForwardIt result = first;
    while ( first != last - 1) {
        if ( !p( *first, *( first + 1))) {
            *result = *first;
            ++result;
        }
        if( first == last - 1) return result;
        ++first;
    }
    return result;
}
模板
ForwardIt removeif(ForwardIt first,ForwardIt last,BinaryP){
ForwardIt结果=第一;
while(第一个!=最后一个-1){
如果(!p(*first,*(first+1))){
*结果=*第一;
++结果;
}
if(first==last-1)返回结果;
++第一,;
}
返回结果;
}
但您必须使其符合您的需要。这完全取决于您如何处理元素对,如果谓词返回true,您是希望删除这两个元素,还是希望删除其中一个?仅左还是仅右?等等

用法:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

bool bp (int left, int right) { return ( left + right == 2); }
/*
 * 
 */
int main(int argc, char** argv) {

    int a[] = { 0, 2, 1, 3, 0, 2, 3, 2, 0, 3, 8};
    std::vector<int> v( a, a + 11);
    std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, ","));
    std::cout << std::endl;
    std::vector<int>::iterator it = removeif( v.begin(), v.end(), bp);
    std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, ","));
    v.erase( it, v.end()); std::cout << std::endl;
    std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, ","));
    return 0;
}
#包括
#包括
#包括


如果条件成立,此版本将删除这两个元素

template<class ForwardIt, class BinaryPredicate>
ForwardIt removeif(ForwardIt first, ForwardIt last, BinaryPredicate p) {

    ForwardIt result = first;
    while (first != last - 1) {
        if (!p(*first, *(first + 1))) {
            *result++ = *first++;
            *result++ = *first++;
        } else {
            if (first == last - 1) return result;
            ++first;
            ++first;
        }
    }
    return result;
}
模板
ForwardIt removeif(ForwardIt first,ForwardIt last,BinaryP){
ForwardIt结果=第一;
while(第一个!=最后一个-1){
如果(!p(*first,*(first+1))){
*结果+=*第一个++;
*结果+=*第一个++;
}否则{
if(first==last-1)返回结果;
++第一,;
++第一,;
}
}
返回结果;
}
0,2,1,3,0,2,3,2,0,3,8

1,3,3,2,0,3,3,2,0,3,8


1,3,3,2,0,3,

为什么在这里需要一个范围?既然你最终通过了开始和结束?无效测试\u擦除(my\u it,my\u it end)我想这只是展示这个想法的一个最简单的例子。去掉范围也很好。重点不是构造像
vector
map
string
这样的对象,想法是将开始和结束迭代器传递给函数,然后根据谓词创建迭代器范围来删除?如果是或简单的I,为什么不删除畸胎?因为remove_if谓词只接受迭代器的值(
*it
),不允许检查邻居的值。非常感谢!我明白了这个想法,现在我可以完成我的代码了
template<class ForwardIt, class BinaryPredicate>
ForwardIt removeif(ForwardIt first, ForwardIt last, BinaryPredicate p) {

    ForwardIt result = first;
    while (first != last - 1) {
        if (!p(*first, *(first + 1))) {
            *result++ = *first++;
            *result++ = *first++;
        } else {
            if (first == last - 1) return result;
            ++first;
            ++first;
        }
    }
    return result;
}