【发布时间】:2010-11-29 17:56:15
【问题描述】:
在 C++ 中没有 std::copy_if 算法有什么具体原因吗?我知道我可以使用 std::remove_copy_if 来实现所需的行为。我认为它是在 C++0x 中出现的,但是一个简单的 copy_if 需要一个范围、一个输出迭代器和一个仿函数会很好。只是错过了,还是有其他原因?
【问题讨论】:
-
它将被添加到下一个标准中。目前的草案在算法库的第 25.2.1 章中有它。
在 C++ 中没有 std::copy_if 算法有什么具体原因吗?我知道我可以使用 std::remove_copy_if 来实现所需的行为。我认为它是在 C++0x 中出现的,但是一个简单的 copy_if 需要一个范围、一个输出迭代器和一个仿函数会很好。只是错过了,还是有其他原因?
【问题讨论】:
根据 Stroustrup 的“C++ 编程语言”,这只是一种疏忽。
(作为引用,在 boost 邮件列表中回答了相同的问题:copy_if)
【讨论】:
copy_if 算法纠正了这一疏忽:en.cppreference.com/w/cpp/algorithm/copy
Stroustrup 说他们忘记了。它在 C++11 中。
但是,您可以同时使用remove_copy_if(实际上应该称为copy_if_not)和not1。
【讨论】:
为了完整起见,如果有人用谷歌搜索这个问题,应该提到现在(C++11 后)有copy 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);
});
【讨论】:
【讨论】:
remove_copy_if,并故意将copy_if 排除在外。但说真的,拥有remove_copy_if 而不是copy_if 显然是某种错误,如果只是一种品味:-)
自己写很容易:
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;
}
【讨论】:
*(result++) = *first;
result 是OutputIterator,那你为什么要给它分配*first?您的代码是错误的,@Peter Kovacs 是正确的。
为了完整起见,我要补充一点,对于那些不能在 boost/algorithm/cxx11/copy_if.hpp 中使用 c++11 版本(比如我)的人,boost 有 boost::algorithm::copy_if,它们将在以下情况下使用 std::copy_if:
#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
【讨论】: