boost::function
erlaubt alles mit einem operator()
mit der richtigen Signatur, die als Parameter gebunden werden soll, und das Ergebnis Ihrer Bindung kann mit einem Parameter aufgerufen werden int
so kann es gebunden werden an function<void(int)>
.
So funktioniert es (diese Beschreibung gilt gleichermaßen für std::function
):
boost::bind(&klass::member, instance, 0, _1)
gibt ein Objekt wie dieses zurück
struct unspecified_type
{
... some members ...
return_type operator()(int i) const { return instance->*&klass::member(0, i);
}
wo die return_type
y int
werden aus der Signatur von klass::member
und der Funktionszeiger und der gebundene Parameter sind tatsächlich im Objekt gespeichert, aber das ist nicht wichtig
Jetzt, boost::function
führt keine Typenprüfung durch: Es nimmt ein beliebiges Objekt und eine beliebige Signatur, die Sie in seinem Template-Parameter angeben, und erstellt ein Objekt, das gemäß Ihrer Signatur aufrufbar ist, und ruft das Objekt auf. Wenn das unmöglich ist, ist es ein Kompilierfehler.
boost::function
ist eigentlich ein Objekt wie dieses:
template <class Sig>
class function
{
function_impl<Sig>* f;
public:
return_type operator()(argument_type arg0) const { return (*f)(arg0); }
};
wo die return_type
y argument_type
werden extrahiert aus Sig
und f
wird dynamisch auf dem Heap zugewiesen. Das ist notwendig, damit völlig unverbundene Objekte mit unterschiedlichen Größen sich an boost::function
.
function_impl
ist nur eine abstrakte Klasse
template <class Sig>
class function_impl
{
public:
virtual return_type operator()(argument_type arg0) const=0;
};
Die Klasse, die die ganze Arbeit macht, ist eine konkrete Klasse, die von boost::function
. Es gibt eine für jede Art von Objekt, das Sie zuordnen 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); }
};
Das heißt in Ihrem Fall, die Zuordnung zur Boost-Funktion:
- instanziiert einen Typ
function_impl_concrete<void(int), unspecified_type>
(das ist natürlich die Kompilierzeit)
- erzeugt ein neues Objekt dieses Typs auf dem Heap
- weist dieses Objekt dem f-Mitglied von boost::function zu
Wenn Sie das Funktionsobjekt aufrufen, ruft es die virtuelle Funktion seines Implementierungsobjekts auf, die den Aufruf an Ihre ursprüngliche Funktion weiterleitet.
DISCLAIMER: Beachten Sie, dass die Namen in dieser Erklärung absichtlich erfunden sind. Jede Ähnlichkeit mit realen Personen oder Charakteren ... Sie wissen es. Der Zweck war, die Prinzipien zu illustrieren.
0 Stimmen
Duplikat: stackoverflow.com/questions/112738/
1 Stimmen
Nicht wirklich - in dieser Frage geht es um Bindung und Funktion
0 Stimmen
Ja, und damit bleibt immer noch die Frage, wie man map void MyClass:DoSomething(std::string str, int number) zu boost::function<void(int)> über bind(&MyClass::DoSomething, instance, "Hello World", _1) binden kann.
2 Stimmen
20.000 Besuche heilige Kuh, das muss in die erhöhen Titelseite!