Boost function

Rileggendo Beyond the C++ Standard Library: An Introduction to Boost di Björn Karlsson.

Parte sull'uso di function, nel capitolo undicesimo, all'interno della terza parte, dedicata ai functor e alla programmazione di più alto ordine.

Con boost::function si semplifica la gestione dei puntatori a funzione, permettendo di usare per lo stesso scopo anche functor e qualunque oggetto che si comporti come una funzione.

#include <iostream>
#include "boost/function.hpp"

using namespace std;

bool check(int i, double d) {
return i > d;
}

void function01() {
boost::function<bool (int, double)> f = ✓

if(f(10, 1.1))
cout << "Function works as expected" << endl;
}

Callback

Una tipica situazione in cui boost::function ci viene in aiuto, e quando vogliamo gestire dei callback. Nell'esempio che segue confrontiamo l'uso normale, con puntatori a funzione nella classi Notifier, con quello di boost::function, in Notifier2.

A parte la definizione del tipo che parametrizza il vettore, il codice non cambia. Il comportamento é lo stesso, ma usando boost::function ci guadagnamo in genericità. Infatti, oltre a puntatori a funzione, possiamo anche utilizzare functor per fare la nostra callback.

#include <iostream>
#include <vector>

#include "boost/function.hpp"

using namespace std;

void printNewValue(int i) {
cout << "The value has been updated and is now " << i << endl;
}

void changeObserver(int i) {
cout << "Ah, the value has changed!" << endl;
}

class PrintPreviousValue {
int lastValue_;
public:
PrintPreviousValue() : lastValue_(-1) {}

void operator()(int i) {
cout << "Previous value was " << lastValue_ << endl;
lastValue_ = i;
}
};

class Notifier {
typedef void (*FunType)(int);
vector<FunType> vec_;
int value_;
public:
void addObserver(FunType t) {
vec_.push_back(t);
}

void changeValue(int i) {
value_ = i;
for (size_t i=0; i < vec_.size(); ++i) {
vec_[i](value_);
}
}
};

class Notifier2 {
typedef boost::function<void(int)> FunType;
vector<FunType> vec_;
int value_;
public:
void addObserver(FunType t) {
vec_.push_back(t);
}

void changeValue(int i) {
value_ = i;
for (size_t i = 0; i < vec_.size(); ++i) {
vec_[i](value_);
}
}
};

void function02() {
Notifier n;
n.addObserver(&printNewValue);
n.addObserver(&changeObserver);

n.changeValue(42);

cout << "Using boost::function" << endl;
Notifier2 n2;
n2.addObserver(&printNewValue);
n2.addObserver(&changeObserver);
n2.addObserver(PrintPreviousValue());

n2.changeValue(42);
n2.changeValue(39);
}

Nessun commento:

Posta un commento