为什么没有std :: copy_ifalgorithm?
在C ++中没有std :: copy_ifalgorithm有什么特别的原因吗? 我知道我可以使用std :: remove_copy_if来实现所需的行为。 我认为它是来自C ++ 0x,但是一个简单的copy_if,它需要一个范围,一个输出迭代器和一个函数。 它只是简单地错过了或者有其他原因背后呢?
根据Stroustrup的“C ++编程语言”,这只是一个看不见的东西。
(作为引用,同样的问题在boost邮件列表中得到了答复: copy_if )
Stroustrup说他们忘记了。 它在C ++ 11中。
但是,您可以使用remove_copy_if
(实际上应该称为copy_if_not
)与not1
一起使用。
为了完整起见,如果有人用他/她的方式来解决这个问题,应该提到现在(在C ++ 11之后) 有一个复制ifalgorithm。 它的行为如预期的那样(将一个范围内的元素(某些谓词返回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); });
有多个 消息来源 表明 ,这是因为意外而被排除在STL之外的。
但是,我不确定这是一个事实还是一个自我延续的神话。 如果有人会指出一个比在互联网上任意发布的链接更可信的消息来源,我将不胜感激。
编写自己的代码非常简单:
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)); }
编辑:这个版本适用于所有的谓词:
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; }
只是为了完整性,我会补充说,boost boost::algorithm::copy_if
对于那些不能在boost/algorithm/cxx11/copy_if.hpp
中使用c ++ 11的版本(如我)的人boost/algorithm/cxx11/copy_if.hpp
,它将使用std::copy_if
boost/algorithm/cxx11/copy_if.hpp
:
#if __cplusplus >= 201103L // Use the C++11 versions of copy_if if it is available using std::copy_if; // Section 25.3.1 #else
例:
#include <boost/algorithm/cxx11/copy_if.hpp> #include <boost/assign/list_of.hpp> // for 'list_of()' #include <boost/foreach.hpp> #include <iostream> #include <vector> #include <iterator> struct Odd { bool operator()(int n) { return n & 1; } }; int main() { std::vector<int> v = boost::assign::list_of(0)(1)(2)(3)(4); BOOST_FOREACH(int i, v) std::cout << i << ' ' ; std::vector<int> out; boost::algorithm::copy_if(v.begin(), v.end(), std::back_inserter(out), Odd()); std::cout << std::endl; BOOST_FOREACH(int i, out) std::cout << i << ' ' ; }
输出:
0 1 2 3 4 1 3