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