Czy istnieje jakiś szczególny powód, dla którego nie ma algorytmu std :: copy_if w C++? Wiem, że mogę użyć std :: remove_copy_if, aby osiągnąć wymagane zachowanie. Myślę, że nadchodzi w C++ 0x, ale prosty copy_if, który ma zasięg, iterator wyjściowy i funktor byłby miły. Czy to było po prostu pominięte, czy jest jakiś inny powód?Dlaczego nie ma algorytmu std :: copy_if?
Odpowiedz
Zgodnie z "Językiem programowania w C++" Stroustrupa było to tylko przesłuchanie.
(jako cytat, to samo pytanie odpowiedział przypominającego Mail-list: copy_if)
Jako aktualizacja, standard C++ 11 poprawił to przeoczenie, dodając nowe 'copy_if' Algorytm: http://en.cppreference.com/w/cpp/algorithm/copy –
sourcesindicate że został przypadkowo pominięty przez STL.
Jednak nie jestem pewien, czy to fakt, czy też samonaprawiający się mit. Byłbym wdzięczny, gdyby ktoś wskazał źródło bardziej wiarygodne niż link do losowego postu w Internecie.
Oto nieprzypadkowy post w Internecie, wybrany na podstawie tego, że twierdzi, że jest e-mailem od Stroustrup do listy mailingowej Boost: http://lists.boost.org/Archives/boost/2001/01/8030.php. Oczywiście może to być oszustwo, albo może Stroustrup sam kupił mit. Sądzę, że jest możliwe, że Stepanov ogólnie uważał, że najlepiej jest mieć 'remove_copy_if' i celowo wykluczyć' copy_if' jako redundantne.Ale poważnie, to jest jakaś pomyłka mieć 'remove_copy_if' ale nie' copy_if', jeśli tylko jeden ze smaku :-) –
Stroustrup mówi, że zapomniał. Jest w C++ 11.
Można jednak użyć remove_copy_if
(która naprawdę powinna nazywać się copy_if_not
), a zamiast tego not1
.
Zawsze tłumaczę "remove_copy_if" na "copy_except" :) – StackedCrooked
... o ile jesteś gotów zaakceptować ten standard :: not1 nie jest kompatybilny ze wskaźnikiem funkcji. (Jak widzę, zostało to omówione poniżej ...) –
To martwy łatwe do pisania własnych:
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: Wersja ta współpracuje ze wszystkimi orzeczników:
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;
}
To nie jest właściwie poprawne, jak zauważono w * Effective STL * item 36, ponieważ działa tylko na funfigurowalnych funktorach. – rlbond
wygląda na to, że to nie jest tak łatwe, wydaje się, że twoja druga próba zwraca pierwszą wartość zgodną z predykatem - poza tym, IMHO, jesteś trochę nie na temat tutaj – rotoglup
rotoglup - Obawiam się, że nie wiesz co mówisz o. "wynik" to OutputIterator. Zrobiłem test tego kodu, który znasz. –
Tylko dla kompletności, w przypadku gdy ktoś google jego/jej drogę do to pytanie, należy wspomnieć, że teraz (po C++ 11) istnieje algorytm. Zachowuje się zgodnie z oczekiwaniami (kopiuje elementy w zakresie, dla którego niektóre predykaty zwraca wartość true, do innego zakresu).
Typowy przypadek użycia byłby
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);
});
Tylko dla kompletności dodam, że impuls ma boost::algorithm::copy_if
dla tych z was, którzy nie mogą korzystać z C++ wersja 11 za (jak ja) w boost/algorithm/cxx11/copy_if.hpp
który użyje std::copy_if
gdy jest :
#if __cplusplus >= 201103L
// Use the C++11 versions of copy_if if it is available
using std::copy_if; // Section 25.3.1
#else
przykład:
#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 << ' ' ;
}
Wyjście:
0 1 2 3 4
1 3
- 1. Dlaczego nie ma std :: inplace_merge_unique?
- 2. Dlaczego nie ma std :: stou?
- 3. Dlaczego nie ma std :: protect?
- 4. Dlaczego nie ma operatora [] dla std :: list?
- 5. Dlaczego std :: move na std :: unique_lock nie ma żadnego efektu?
- 6. Dlaczego nie ma konstruktora rezerwującego dla std :: string?
- 7. Dlaczego nie ma IntStream.flatMapToObj()?
- 8. Dlaczego nie ma jednolitej_dystrybucji?
- 9. Przestrzeń nazw "std" nie ma członka "sort"
- 10. std :: set nie ma członka emplace
- 11. Dlaczego C++ 11 nie ma szablonu typedef?
- 12. Czas działania algorytmu A wynosi co najmniej O (n²) - Dlaczego nie ma znaczenia?
- 13. Dlaczego std :: lock_guard/std :: unique_lock nie używa typu wymazania?
- 14. Dlaczego std :: swap bitów w instancji std :: bitset nie działa?
- 15. Dlaczego nie możemy trywialnie skopiować std :: function
- 16. Dlaczego nie ma UTF-24?
- 17. Dlaczego Python nie ma przełącznika?
- 18. Dlaczego Scala nie ma decltype?
- 19. Deque - dlaczego nie ma "rezerwy"?
- 20. Dlaczego nie ma obiektu StrongReference?
- 21. Dlaczego SLComposeViewController nie ma delegata?
- 22. Czy nie ma specjalizacji od std :: hash dla standardowych kontenerów?
- 23. Dlaczego blokowania std :: mutex nie blokuje nić
- 24. Dlaczego std :: timed_mutex :: try_lock_for nie działa?
- 25. Dlaczego funkcja dodawania nie ma wpływu w wątku C++ 11?
- 26. std :: condition_variable dlaczego potrzebuje std :: mutex
- 27. Dlaczego std :: this_thread namespace?
- 28. Dlaczego std :: less jest szablonem klasy?
- 29. Dlaczego std :: array nie ma konstruktora, który pobiera wartość do wypełnienia tablicy?
- 30. Jak uzyskać indeks elementu z predykatu przekazanego do jakiegoś algorytmu STL?
+1 Nigdy nie myślałem o tym. – AraK
Zostanie dodany do następnego standardu. Obecny projekt ma go w rozdziale 25.2.1 w bibliotece algorytmów. –
Duplikat: http://stackoverflow.com/questions/794320/are-they-adding-copyif-to-c0x –