mardi 20 janvier 2009

functional abstraction of data members with boost::bind

I just wanted to share a little trick I learned some time ago : you can use boost::bind to transform pointers to data members into functors.

For example, if you have a struct that looks like this :


struct my_struct
{
explicit my_struct( int value )
:m_some_member( value )
{
}
int m_some_member;
};


You can use boost::bind( &my_struct::m_some_member, _1 ) as a valid functor that will take an instance of my_struct as a parameter and return an int.

Admit it, it's pretty cool :-) You don't have to write the getter, bind will generate it for you.

What this kind of technique does to code readability is a matter you have to consider if you want to use it in a professional environment... I myself would most definitely write the getter in the vast majority of situations.

It's always fun to close with a little program that shows I cared enough to test the subject prior to publication ; here it is


#include <iostream>
#include <algorithm>
#include <vector>
#include <boost/bind.hpp>

struct my_struct
{
explicit my_struct( int value )
:m_some_member( value )
{
}
int m_some_member;
};

struct printer
{
typedef void result_type;
template< typename T >
inline void operator()( const T& anything )
{
std::cout << anything << std::endl;
}
};

int main()
{
std::vector< my_struct > my_vector;
my_vector.push_back( my_struct( 0 ) );
my_vector.push_back( my_struct( 1 ) );
my_vector.push_back( my_struct( 1 ) );
my_vector.push_back( my_struct( 2 ) );
my_vector.push_back( my_struct( 3 ) );
my_vector.push_back( my_struct( 5 ) );
std::for_each(
my_vector.begin(), my_vector.end(),
boost::bind( printer(),
boost::bind( &my_struct::m_some_member, _1 ) ) );
return 0;
}

Aucun commentaire: