views:

568

answers:

3

Hello experts

I have been trying to emulate a copy_if by the following codes but my compiler (g++-4.0) just keeps complaining. What's technically wrong? Thanks for your help!

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)
  )
 );
}
+1  A: 

For reference, here's a more normal implementation of copy_if, taken from 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;
}

Then you'd use it like:

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

Assuming of course that the line I've copied isn't the line which fails in your code.

Steve Jessop
A: 

My guess is the compiler does not like the line

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

I wonder if it's failing to find the right operator method from the bind object and not the _1. You should try wrapping it in another lambda expression.

Think of it this way:

(_1 == OK)(boost::lambda::bind(&A::get_StatusTag, boost::lambda::_1))
amado
The compiler can handle the first statement if you include the <boost/lambda/lambda.hpp> header.
SYK
+5  A: 

lambda::bind binds by copy. The expression bind(&STL::push_back, AList, _1) thus creates a functor holding a copy of AList. Since this functor's operator() is const, applying it fails because it ends up calling a non-const member (push_back) on a const object (its internal copy).

Solution: bind to a reference to AList, using: bind(&STL::push_back, boost::ref(AList), _1)

Éric Malenfant