1 votes

boost::lambda::if_then pour copy_if

J'ai essayé d'émuler un copy_if avec les codes suivants mais mon compilateur (g++-4.0) ne cesse de se plaindre. Quel est le problème technique ? Merci pour votre aide !

template <class STL> // a std container of class A, but I don't know if it's a list or vector or deque
void export_(STL& Alist) { //a member function
    for_each(Alist0.begin(), Alist0.end(), //member data
        boost::lambda::if_then(
            boost::lambda::bind(&A::get_StatusTag, boost::lambda::_1) == OK, //some global enum returned by A::get_StatusTag
            boost::lambda::bind(&STL::push_back, Alist, boost::lambda::_1)
        )
    );
}

5voto

Éric Malenfant Points 10082

Lambda::bind se lie par copie. L'expression bind(&STL::push_back, AList, _1) crée donc un foncteur contenant un copie de AList. Puisque l'operator() de ce foncteur est const, son application échoue car elle finit par appeler un membre non const (push_back) sur un objet const (sa copie interne).

Solution : se lier à un référence à AList, en utilisant : bind(&STL::push_back, boost::ref(AList), _1)

1voto

Steve Jessop Points 166970

Pour référence, voici une implémentation plus normale de copy_if, tirée de http://www.richelbilderbeek.nl/CppCopy_if.htm

template<typename In, typename Out, typename Pred>
Out copy_if(In first, In last, Out res, Pred Pr)
{
  while (first != last)
  {
    if (Pr(*first))
      *res++ = *first;
    ++first;
  }
  return res;
}

Alors tu l'utiliserais comme :

template <typename BackInsertionSequence>
void export_(BackInsertionSequence &Alist) {
    copy_if(AList0.begin(), AList0.end(), std::back_inserter(Alist),
        boost::lambda::bind(&A::get_StatusTag, boost::lambda::_1) == OK
    );
}

En supposant bien sûr que la ligne que j'ai copiée n'est pas la ligne qui échoue dans votre code.

0voto

amado Points 11

Je pense que le compilateur n'aime pas la ligne

boost::lambda::bind(&A::get_StatusTag, boost::lambda::_1) == OK

Je me demande s'il n'est pas en train d'échouer à trouver la bonne méthode d'opérateur à partir de l'objet bind et non du _1. Vous devriez essayer de l'envelopper dans une autre expression lambda.

Pensez-y de cette façon :

(_1 == OK)(boost::lambda::bind(&A::get_StatusTag, boost::lambda::_1))

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