【问题标题】:c++ understanding the third argument of `remove_if()` [closed]c ++理解`remove_if()`的第三个参数[关闭]
【发布时间】:2018-09-09 12:52:05
【问题描述】:

我试图理解remove_if() 算法中的第三个参数。根据description,如果函数返回 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());

【问题讨论】:

  • "但是该函数不返回布尔值。"事实上,确实如此。
  • 您展示的代码是erase remove idiom的示例
  • 忘记 cplusplus dot com:它很糟糕而且已经过时。去看看 cppreference.com。这就是好东西的所在。

标签: c++ algorithm stl remove-if


【解决方案1】:

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

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

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

remove_if() 是否真的删除了元素?

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

【讨论】:

    【解决方案2】:

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

    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);
    

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

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

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

    算法实际上并不删除元素。它们将它们移动到范围的末尾,并返回结果范围的末尾,即移动“已删除”元素后的实际元素范围。

    调用成员函数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 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-04
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-19
      • 2010-12-07
      • 1970-01-01
      相关资源
      最近更新 更多