为什么没有std :: copy_if算法?

Nav*_*een 63 c++ algorithm stl

在C++中没有std :: copy_if算法的具体原因是什么?我知道我可以使用std :: remove_copy_if来实现所需的行为.我认为它是在C++ 0x中出现的,但是一个简单的copy_if需要一个范围,一个输出迭代器和一个仿函数就可以了.它只是简单地错过了还是还有其他原因呢?

sbk*_*sbk 41

根据Stroustrup的"The C++ Programming Language",它只是一个过度的观点.

(作为引用,在提升邮件列表中回答了同样的问题:copy_if)

  • 作为更新,C++ 11标准通过添加新的`copy_if`算法纠正了这种疏忽:http://en.cppreference.com/w/cpp/algorithm/copy (9认同)

rlb*_*ond 27

Stroustrup说他们忘记了.它是在C++ 11中.

但是,您可以使用remove_copy_if(实际应该被称为copy_if_not)not1.

  • 在我看来,我总是将"remove_copy_if"翻译为"copy_except":) (6认同)

Nik*_*iou 9

只是为了完整性,如果有人用谷歌搜索他/她的方式来解决这个问题,应该提到现在(在C++ 11之后)一个副本if算法.它的行为与预期一致(将某个谓词返回true的范围内的元素复制到另一个范围).

一个典型的用例是

std::vector<int> foo{ 25, 15, 5, -5, -15 };
std::vector<int> bar;

// copy only positive numbers:
auto it = std::copy_if (foo.begin(), foo.end(), std::back_inserter(bar), 
            [](int i){return !(i<0);
          });
Run Code Online (Sandbox Code Playgroud)


Ale*_*x B 7

多个 来源 表明它被意外地排除在STL之外.

但是,我不确定这是一个事实还是一个自我延续的神话.如果有人能指出一个比互联网随机帖子的链接更可信的来源,我将不胜感激.

  • 这是互联网上的一篇非随机帖子,根据它声称是Stroustrup到Boost邮件列表的电子邮件进行选择:http://lists.boost.org/Archives/boost/2001/01/8030.php .当然这可能是欺诈,或者可能是Stroustrup自己已经买了这个神话.我猜Stepanov一般认为最好有'remove_copy_if`,并故意将`copy_if`排除在外.但严重的是,如果只有一个品味的话,显然有一些错误:"remove_copy_if"而不是"copy_if".-) (4认同)

ale*_*gle 7

编写自己的东西很容易:

template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator copy_if(InputIterator first, InputIterator last,
                       OutputIterator result, Predicate pred)
{
  return std::remove_copy_if(first,last,result,std::not1(pred));
}
Run Code Online (Sandbox Code Playgroud)

编辑:此版本适用于所有谓词:

template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator copy_if(InputIterator first, InputIterator last,
                       OutputIterator result, Predicate pred)
{
  while(first!=last)
  {
    if(pred(*first))
        *result++ = *first;
    ++first;
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

  • 你不必迭代OutputIterator吗?`*(result ++)=*first;` (4认同)
  • @Peter&Troubadour - 当然你们都是对的.Mea culpa.我编写的代码实际上工作,但可能只是因为实现细节和我的测试代码之间的一些疯狂的交集.我已经纠正过了,给你+1了. (3认同)
  • 这实际上并不正确,如*Effective STL*item 36中所述,因为它仅适用于适应性仿函数. (2认同)