boost::function
permet n'importe quoi avec un operator()
avec la bonne signature à être liée en tant que paramètre, et le résultat de votre liaison peut être appelé avec un paramètre int
, de sorte qu'il peut être lié à function<void(int)>
.
Voilà comment cela fonctionne (cette description s'applique aussi bien pour std::function
):
boost::bind(&klass::member, instance, 0, _1)
retourne un objet comme celui-ci
struct unspecified_type
{
... some members ...
return_type operator()(int i) const { return instance->*&klass::member(0, i);
}
où le return_type
et int
sont déduits de la signature de klass::member
, et pointeur de fonction et paramètre lié sont en fait stockés dans l'objet, mais ce n'est pas important
Maintenant, boost::function
fait ne pas faire de vérification de type: il prendra tout objet et toute signature que vous fournissez dans son paramètre de modèle, et créera un objet qui est appelable selon votre signature et appellera l'objet. Si c'est impossible, c'est une erreur de compilation.
boost::function
est en fait un objet de ce type:
template <class Sig>
class function
{
function_impl<Sig>* f;
public:
return_type operator()(argument_type arg0) const { return (*f)(arg0); }
};
où le return_type
et argument_type
sont extraits de Sig
, et f
est allouée dynamiquement sur le tas. Cela est nécessaire pour autoriser des objets complètement indépendants avec des tailles différentes à 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 une classe concrète dérivée de boost::function
. Il y 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 à stimuler la fonction:
- instancie un type
function_impl_concrete<void(int), unspecified_type>
(qui est la compilation, bien sûr)
- crée un nouvel objet de ce type sur le tas
- attribue cet objet à l'élément f de boost :: fonction
Lorsque vous appelez l'objet de fonction, il appelle la fonction virtuelle de son objet de mise en œuvre, qui dirigera l'appel à votre fonction d'origine.AVIS DE NON-RESPONSABILITÉ: Notez que les noms de cette explication sont délibérément constitués. Toute ressemblance avec de vraies personnes ou personnages ... vous le savez. Le but était d'illustrer les principes.
Dupe: http://stackoverflow.com/questions/112738/how-does-boost-bind-work-behind-the-scenes-in-general –
pas vraiment - cette question est sur la liaison et la fonction –
Oui et donc cela laisse toujours la question de savoir comment peut lier la carte void MyClass: DoSomething (std :: chaîne str, nombre entier) à boost :: fonction via bind (& MyClass :: DoSomething, instance, "Bonjour le monde", _1) –