boost::function
permet à quoi que ce soit avec un operator()
avec le bouton droit de signature à être lié comme paramètre, et le résultat de votre bind peut être appelée avec un paramètre int
, de sorte qu'il peut être lié à l' function<void(int)>
.
Voilà comment cela fonctionne (cette description s'applique aussi bien pour l' std::function
):
boost::bind(&klass::member, instance, 0, _1)
renvoie un objet comme celui-ci
struct unspecified_type
{
... some members ...
return_type operator()(int i) const { return instance->*&klass::member(0, i);
}
où l' return_type
et int
sont déduits à partir de la signature de l' klass::member
, et le pointeur de fonction et paramètre de limite sont en fait stockées dans l'objet, mais ce n'est pas important
Maintenant, boost::function
n'est pas n'importe quel type de vérification: Il faudra tout objet et de toute signature vous fournir dans son paramètre du modèle, et de créer un objet appelable en fonction de votre signature et appelle l'objet. Si c'est impossible, c'est une erreur de compilation.
boost::function
est en fait un objet comme ceci:
template <class Sig>
class function
{
function_impl<Sig>* f;
public:
return_type operator()(argument_type arg0) const { return (*f)(arg0); }
};
où l' return_type
et argument_type
sont extraits d' Sig
, et f
est allouée dynamiquement sur le tas. C'est nécessaire pour permettre complètement indépendants des objets avec différentes tailles de lier boost::function
.
function_impl
est juste une classe abstraite
template <class Sig>
class function_impl
{
public:
virtual return_type operator()(argument_type arg0) const=0;
};
La classe qui fait tout le travail, est un béton de classe dérivée de l' boost::function
. Il y en a un pour chaque type d'objet que vous attribuez à boost::function
template <class Sig, class Object>
class function_impl_concrete : public function_impl<Sig>
{
Object o
public:
virtual return_type operator()(argument_type arg0) const=0 { return o(arg0); }
};
Cela signifie que dans votre cas, l'affectation à la fonction "boost":
- instancie un type
function_impl_concrete<void(int), unspecified_type>
(c'est le moment de la compilation, bien sûr)
- crée un nouvel objet de ce type sur le tas
- attribue cet objet au f membre de boost::function
Lorsque vous appelez la fonction de l'objet, il appelle la fonction virtuelle de sa mise en œuvre, de l'objet, qui va diriger l'appel vers votre fonction d'origine.
AVERTISSEMENT: veuillez Noter que les noms de cette explication sont volontairement. Toute ressemblance avec des personnes réelles ou des personnages ... vous le savez. Le but était d'illustrer les principes.