c ++理解`remove_if()`的第三个参数

时间:2018-03-30 13:10:58

标签: c++ algorithm stl remove-if

我试图理解remove_if()算法中的第三个参数。根据{{​​3}},如果函数返回true,则应删除它。但是该函数不返回bool[](char c)的语法是什么?

remove_if()实际上是否删除了该元素?如果是这样,为什么之后会打电话给erase()

std::string S("AA BB-4499--5");
auto newEnd = std::remove_if(S.begin(), S.end(), [](char c){return c == ' ' || c == '-';});
S.erase(newEnd, S.end());

2 个答案:

答案 0 :(得分:2)

  

[](char c)的语法是什么?

这是C ++ 11及更高版本中的lambda语法。

在这种情况下,它被用作谓词,remove_if调用它来决定要删除哪些元素。

  

remove_if()实际上是否删除了元素?

不,它只是移动"删除"元素到字符串的末尾,然后将迭代器返回到第一个"删除"元件。后续erase()实际上从字符串中删除了元素。这称为erase-remove idiom

答案 1 :(得分:1)

有两种版本的删除(无复制)算法。他们是

template<class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
const T& value);

template<class ForwardIterator, class Predicate>
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
Predicate pred);

算法的第一个变体&#34;删除&#34;容器中满足条件*i == value的所有元素,其中i[first, last)范围内的迭代器。

算法的第二个变体&#34;删除&#34;容器中满足条件pred(*i) != false的所有元素,其中i[first, last)范围内的迭代器。

实际上,谓词在if语句中使用,其值在上下文中被转换为bool类型。

算法实际上并不删除元素。他们将它们移动到范围的末尾并返回结果范围的结束,该范围是移动后移除的实际元素范围&#34;删除&#34;元件。

调用成员函数erase会导致实际删除这些元素。

考虑以下示范计划。

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

int main() 
{
    std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    auto last = std::remove_if( v.begin(), v.end(), []( int x ) { return x % 2; } );

    for ( int x : v ) std::cout << x << ' ';
    std::cout << std::endl;

    for ( auto first = v.begin(); first != last; ++first )
    {
        std::cout << *first << ' ';
    }

    std::cout << "||| ";

    for ( auto first = last; first != v.end(); ++first )
    {
        std::cout << *first << ' ';
    }

    std::cout << std::endl;

    v.erase( last, v.end() );

    for ( int x : v ) std::cout << x << ' ';
    std::cout << std::endl;

    return 0;
}

它的输出是

0 2 4 6 8 5 6 7 8 9 
0 2 4 6 8 ||| 5 6 7 8 9 
0 2 4 6 8