Search code examples
c++boost-phoenix

phoenix lambda and argument dereferencing


Can somebody show me how to implement an equivalent of the following using boost::phoenix lambda? I know I could implement it in many other ways but I'm trying to learn the Phoenix lambda expressions and so far all my attempts in this example failed.

What I want to do is to use the std::remove_if to iterate through my set of weak_ptrs and remove the expired ones.

So the code would look something like:

typedef std::set<weak_ptr<Xyz>> XyzWptrSetType;
...
XyzWptrSetType   xyzWptrSet;
...
XyzWptrSetType::iterator it =
    std::remove_if(xyzWptrSet.begin(), xyzWptrSet.end(),
                   (boost::phoenix::arg_names::_1->expied()));  
// the lambda part DOESN'T compile in previous line
std::erase(it, xyzWptrSet.end());

Most of the lambda examples I've found are very simplistic and do not deal with calling a member function on a lambda argument object especially when there is more than one level of indirection. I.e. the _1 is expected to represent the set's iterator which by dereferencing with "->" returns value_type (being weak_ptr), on which I want to call expired. But since _1 is in fact not dirrectly an iterator but rather an "phoenix::actor", my dereferencing doesn't compile.

Thanks for all the creative inputs in advance.

Gabe


Solution

  • Boost phoenix (and boost lambda) do not support the -> operator. You can use the "pointer to member" operator (->*) as a reasonable alternative.

    I find it useful to define the member pointer as a separate variable immediately before the line that uses a lambda expression:

    bool (weak_ptr<Xyz>::*expired)()const = &weak_ptr<Xyz>::expired ;
    XyzWptrSetType::iterator it =
        std::remove_if(xyzWptrSet.begin(), xyzWptrSet.end(), (&_1->*expired)() );
    

    As others have noted, it is also worth considering bind() for situations like yours.