Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

How Does boost.phoenix Improve boost.bind?

4.64/5 (11 votes)
1 Feb 2015CPOL 33K  
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)