Почему нет алгоритма std::copy if?
есть ли какая-то конкретная причина для отсутствия алгоритма std::copy_if в C++ ? Я знаю, что могу использовать std::remove_copy_if для достижения требуемого поведения. Я думаю, что это происходит в C++0x, но простой copy_if, который принимает диапазон, выходной итератор и функтор, было бы неплохо. Было ли это просто упущено или есть какая-то другая причина?
6 ответов:
согласно "языку программирования C++" Страуструпа, это был просто видимость.
(в качестве цитаты, тот же вопрос ответил в boost mail-lists: copy_if)
Страуструп говорит, что они это забыли. Это в C++11.
однако, вы можете использовать
remove_copy_if
(который действительно должен называтьсяcopy_if_not
) вместе сnot1
вместо.
просто для полноты, в случае, если кто-то гуглит свой путь к этому вопросу, следует упомянуть, что сейчас (post C++11) здесь a скопировать если. Он ведет себя так, как ожидалось (копирует элементы в диапазоне, для которого некоторый предикат возвращает 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); });
это мертво легко написать свой собственный:
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)); }
Edit: эта версия работает со всеми предикатами:
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
для тех из вас, кто не может использовать версию c++11 (как я) вboost/algorithm/cxx11/copy_if.hpp
которая будет использовать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