Click here to Skip to main content
15,881,812 members
Articles / Programming Languages / C++
Tip/Trick

How Does boost.phoenix Improve boost.bind?

Rate me:
Please Sign up or sign in to vote.
4.64/5 (11 votes)
1 Feb 2015CPOL 32.3K   3   5
A quick demonstration of how boost.phoenix makes a messy boost.bind call much easier to read

Introduction

Let's say we have a list of strings:

C++
std::vector< std::string > list;
list.push_back( "duck" );
list.push_back( "duck" );
list.push_back( "goose" );
std::string value = "goose";

We'd like to filter the string "goose" from this list. Using the typical erase-remove idiom, we could do something like this:

C++
bool IsGoose( const std::string& s )
{
    return s == "goose";
} 
list.erase( std::remove_if( list.begin(), list.end(), IsGoose ), list.end() );

Translating this to a lambda function using boost.bind, we get:

C++
list.erase( 
    std::remove_if( 
        list.begin(), 
        list.end(), 
        boost::bind( 
            static_cast< bool( * )( const std::string&, 
                                    const std::string& ) >( 
                &std::operator==<char, std::string::traits_type, std::string::allocator_type> ), 
            _1, 
            boost::cref( value ) ) ), 
    list.end() );

Because the std::operator== is overloaded, we have a very messy looking cast in there to ensure the correct version of the function is selected. Using boost.phoenix[^], we can clean that up a bit:

C++
namespace phx = boost::phoenix;
using phx::placeholders::arg1;
using phx::placeholders::arg2;
 
list.erase( std::remove_if( list.begin(), 
                            list.end(), 
                            arg1 == phx::cref( value ) ), 
            list.end() );

We can even shrink things slightly further by switching to the boost.phoenix remove_if wrapper so that we no longer need to include the iterator range:

C++
list.erase( phx::remove_if( arg1, arg2 )( list, arg1 == phx::cref( value ) ), 
            list.end() );

And that, ladies and gentlemen, is how boost.phoenix can make a complicated and messy lambda expression much simpler.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) An engineering firm in Cedar Rapids, Iowa
United States United States
I'm also on the MSDN forums
http://social.msdn.microsoft.com/profile/paulh79

Comments and Discussions

 
GeneralMy vote of 4 Pin
George L. Jackson6-Feb-15 8:21
George L. Jackson6-Feb-15 8:21 
GeneralRe: My vote of 4 Pin
Paul Heil6-Feb-15 8:51
Paul Heil6-Feb-15 8:51 
GeneralReason for my vote of 4 Excellent reminder to browse Boost t... Pin
Jon Summers6-Sep-11 6:01
Jon Summers6-Sep-11 6:01 
QuestionC++11 lambdas Pin
PeteBarber2-Nov-11 3:09
PeteBarber2-Nov-11 3:09 
AnswerRe: C++11 lambdas Pin
Paul Heil2-Nov-11 3:53
Paul Heil2-Nov-11 3:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.