Есть ли какая-либо конкретная причина для отсутствия алгоритма std:: copy_if в С++? Я знаю, что могу использовать std:: remove_copy_if для достижения требуемого поведения. Я думаю, что он приходит в С++ 0x, но простой экземпляр copy_if, который принимает диапазон, выходной итератор и функтор, был бы приятным. Было ли это просто пропущено или есть какая-то другая причина?
Почему нет алгоритма std:: copy_if?
Ответ 1
Согласно Stroustrup "Язык программирования С++", это был просто перехват.
(как цитата, тот же вопрос ответил в передовых почтовых списках: copy_if)
Ответ 2
Страуструп говорит, что они забыли его. Это в С++ 11.
Однако вы можете использовать remove_copy_if
(который действительно должен называться copy_if_not
) вместе с not1
.
Ответ 3
Просто для полноты, если кто-то пойдет по этому пути на свой вопрос, следует упомянуть, что теперь (post С++ 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);
});
Ответ 4
Несколько источники укажите, что он случайно был исключен из STL.
Однако я не уверен, что это факт или самовоспроизводящийся миф. Я был бы признателен, если бы кто-нибудь указывал, что источник более правдоподобен, чем ссылка на случайную запись в Интернете.
Ответ 5
Он мертв легко писать самостоятельно:
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;
}
Ответ 6
Просто для полноты я добавлю, что boost имеет boost::algorithm::copy_if
для тех из вас, кто не может использовать версию С++ 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