S'il n'y avait qu'une seule chose à retenir de la librairie boost, ce serait certainement boost::bind.
Cette librairie permet d'utiliser de manière relativement simple des pointeurs de fonction ou des pointeurs sur des methodes.
Mais plutôt qu'un long discours, voici un petit programme :
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
// En general, on utilise un typedef, ca simplifie la vie
typedef boost::function<void (int i)> PFunctor;
// Une methode qui illustre l'utilisation
void callFuntor( PFunctor pf ) {
int a=1234;
pf( a );
}
class Test {
public:
void callback1( int a ) {
std::cout << "Test::callback1(" << a << ")\n";
}
void callback2( std::string s, int a ) {
std::cout << "Test::callback2(" << s << "," << a << ")\n";
}
void callback3( int a, std::string s ) {
std::cout << "Test::callback3(" << a << "," << s << ")\n";
}
static void callback4( int a ) {
std::cout << "Test::callback4(" << a << ")\n";
}
};
void coucou( std::string s, int i ) {
std::cout << "coucou s=" << s << " - i=" << i << "\n";
}
int main() {
// utilisation directe: Les _1 et _2 (...) indiquent a boost::bind comment se debrouiller
// avec les arguments.
// Toujours se souvenir que l'ordre des arguments doit correspondre au prototype
// de la fonction appelee
boost::bind( &coucou, "bla", 123 )();
boost::bind( &coucou, "blabla", _1)( 456 );
boost::bind( &coucou, "blablabla", _1 )( 789 );
boost::bind( &coucou, _1, _2)( "blablablabla", 1011 );
boost::bind( &coucou, _2, _1)( 1213, "blablablablabla" );
// passage par une variable. En general, on declare des typedefs plus aises a utiliser.
boost::function<void ()> functor;
functor = boost::bind( &coucou, "ro", 123 );
functor();
boost::function<void (int)> functor2;
functor2 = boost::bind( &coucou, "roro", _1 );
functor2(456);
// exemple d'utilisation de _1
std::vector<int> v;
v.push_back( 123 ); v.push_back( 456 ); v.push_back( 789 );
std::for_each( v.begin(), v.end(), boost::bind( &coucou, "blu", _1 ) );
// Exemple d'utilisation avec une classe. Ce qu'il faut remarquer, c'est qu'on
// passe le pointeur de la classe en premier argument quand il s'agit d'une
// methode non statique
Test t;
// &t = le pointeur en premier
callFuntor( boost::bind( &Test::callback1, &t, _1 ) );
// prototype de callback2 => string puis int
callFuntor( boost::bind( &Test::callback2, &t, "cb2", _1 ) );
// prototype de callback3 => int puis string
callFuntor( boost::bind( &Test::callback3, &t, _1, "cb3" ) );
// callback4 statique, donc pas de this
callFuntor( boost::bind( &Test::callback4, _1 ) );
// Utilisation evidemment possible avec une methode d'une autre classe ou bien
// une fonction, ici, coucou()
// prototype => string, int
callFuntor( boost::bind( &coucou, "fin de l'exemple", _1 ) );
return 0;
}
La sortie écran est la suivante :
$ ./boost coucou s=bla - i=123 coucou s=blabla - i=456 coucou s=blablabla - i=789 coucou s=blablablabla - i=1011 coucou s=blablablablabla - i=1213 coucou s=ro - i=123 coucou s=roro - i=456 coucou s=blu - i=123 coucou s=blu - i=456 coucou s=blu - i=789 Test::callback1(1234) Test::callback2(cb2,1234) Test::callback3(1234,cb3) Test::callback4(1234) coucou s=fin de l'exemple - i=1234