63 votes

Pourquoi n'y a-t-il pas d'algorithme std::copy_if ?

Y a-t-il une raison spécifique pour ne pas avoir l'algorithme std::copy_if en C++ ? Je sais que je peux utiliser std::remove_copy_if pour obtenir le comportement requis. Je pense que c'est prévu dans C++0x, mais un simple copy_if qui prend une plage, un itérateur de sortie et un foncteur aurait été bien. Est-ce que cela a été simplement omis ou y a-t-il une autre raison derrière cela ?

41voto

sbk Points 4987

Selon l'ouvrage de Stroustrup intitulé "The C++ Programming Language", il s'agissait d'une simple erreur de jugement.

(à titre de citation, la même question a reçu une réponse dans les listes de diffusion de boost : copier_f )

27voto

rlbond Points 24215

Stroustrup dit qu'ils l'ont oublié. C'est dans C++11.

Cependant, vous pouvez utiliser remove_copy_if (qui devrait vraiment s'appeler copy_if_not ) ainsi que not1 à la place.

9voto

Nikos Athanasiou Points 7015

Pour être complet, au cas où quelqu'un trouverait la réponse à cette question sur Google, il convient de mentionner que maintenant (après C++11) il y a a copie si algorithme. Il se comporte comme prévu (il copie les éléments d'une plage, pour laquelle un prédicat renvoie vrai, vers une autre plage).

Un cas d'utilisation typique serait

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);
          });

7voto

Alex B Points 34304

Multiple sources indiquer qu'il a été laissé hors de la STL par accident.

Cependant, je ne sais pas si c'est un fait ou un mythe qui s'auto-perpétue. J'apprécierais si quelqu'un pouvait m'indiquer une source plus crédible qu'un lien vers un post aléatoire sur Internet.

7voto

alex tingle Points 3134

C'est très facile d'écrire le sien :

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 : Cette version fonctionne avec tous les prédicats :

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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X