Die Boost C++ Bibliotheken

Kapitel 40. Boost.Function

Boost.Function stellt die Klasse boost::function zur Verfügung, um Funktionszeiger zu kapseln. Die Klasse ist in der Headerdatei boost/function.hpp definiert.

Wenn Sie in einer Entwicklungsumgebung arbeiten, die C++11 unterstützt, haben Sie Zugriff auf eine Klasse std::function. Sie finden sie in der Headerdatei functional. In diesem Fall können Sie Boost.Function ignorieren, da boost::function und std::function gleich sind.

Beispiel 40.1. boost::function in Aktion
#include <boost/function.hpp>
#include <iostream>
#include <cstdlib>
#include <cstring>

int main()
{
  boost::function<int(const char*)> f = std::atoi;
  std::cout << f("42") << '\n';
  f = std::strlen;
  std::cout << f("42") << '\n';
}

Mit boost::function wird ein Zeiger auf eine Funktion mit einer bestimmten Signatur definiert. Im Beispiel 40.1 ist angegeben, dass f auf Funktionen zeigen darf, deren Rückgabewert vom Typ int ist und die einen einzigen Parameter vom Typ const char* erwarten. Einmal definiert können Funktionen an f gebunden werden, deren Signatur kompatibel ist. So werden im Beispiel 40.1 die Funktionen std::atoi() und std::strlen() an f gebunden.

Beachten Sie, dass keine perfekte Übereinstimmung der Typen notwendig ist: Auch wenn std::strlen() so definiert ist, dass diese Funktion einen Rückgabewert vom Typ std::size_t besitzt, kann sie trotzdem an f gebunden werden.

Da f ein Funktionszeiger ist, kann die an f gebundene Funktion über den überladenen Operator operator() aufgerufen werden. Je nachdem, an welche Funktion f gebunden ist, wird im Beispiel 40.1 std::atoi() oder std::strlen() aufgerufen.

Wenn f an keine Funktion gebunden ist, wird bei einem Aufruf die Ausnahme boost::bad_function_call geworfen. Beispiel 40.2 demonstriert dies.

Beispiel 40.2. boost::bad_function_call bei Aufruf ohne Funktionsbindung
#include <boost/function.hpp>
#include <iostream>

int main()
{
  try
  {
    boost::function<int(const char*)> f;
    f("");
  }
  catch (boost::bad_function_call &ex)
  {
    std::cerr << ex.what() << '\n';
  }
}

Beachten Sie, dass Sie durch die Zuweisung von nullptr einen Funktionszeiger vom Typ boost::function zurücksetzen und die Bindung an eine Funktion lösen können. Sollten Sie dann versuchen, eine Funktion aufzurufen, wird ebenfalls eine Ausnahme vom Typ boost::bad_function_call geworfen. Die von boost::function zur Verfügung gestellten Methoden empty() und operator bool können Sie nutzen, um herauszufinden, ob ein Objekt vom Typ boost::function auf eine Funktion verweist.

Boost.Function ermöglicht auch, Methoden an Objekte vom Typ boost::function zu binden. Beim Aufruf muss das Objekt angegeben werden, für das die Methode ausgeführt werden soll. Sehen Sie sich dazu Beispiel 40.3 an.

Beispiel 40.3. Eine Methode an boost::function binden
#include <boost/function.hpp>
#include <functional>
#include <iostream>

struct world
{
  void hello(std::ostream &os)
  {
    os << "Hello, world!\n";
  }
};

int main()
{
  boost::function<void(world*, std::ostream&)> f = &world::hello;
  world w;
  f(&w, std::ref(std::cout));
}

Als erster Parameter muss beim Methodenaufruf das Objekt angegeben werden, für das die an f gebundene Methode ausgeführt werden soll. Das setzt voraus, dass der erste Parameter in runden Klammern bei der Template-Definition ein Zeiger auf die entsprechende Klasse ist. Die nachfolgenden Parameter kennzeichnen die Signatur der entsprechenden Methode.