bind
La STL mette a disposizione bind1st e bind2nd per permettere il binding a functor già esistenti. Boost estende questo concetto con bind.
Per prima cosa, mi rivedo un uso di bind1st:
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
int main () {
int numbers[] = {10,20,30,40,50,10};
int cx = count_if (numbers, numbers+6, bind1st(equal_to<int>(), 10) );
cout << "There are " << cx << " elements that are equal to 10.\n";
}
Chiamo la count_if passando come predicato il functor equal_to che viene adattato dalla bind1st in modo da usare, oltre al parametro passato dalla count_if, ovvero l'elemento corrente nella scansione della sequenza, un valore fisso - 10 nel nostro caso.
Riscrivere questo specifico esempio con boost:bind non porta un gran vantaggio, anzi, a ben vedere, sembra piuttosto una soluzione peggiore, dato che occorre specificare il segnaposto (_1) utilizzato.
Ma boost:bind é più potente di bind1st, e lo vediamo quando vogliamo usare una funzione e non un functor (come é obbligatorio fare per bind1st).
Vero é che spesso é possibile adattare una funzione alle specifiche di bind1st ma questo comporta un appesentimento del codice, e non sempre é possibile farlo.
Altro punto a favore di boost::bind é la possibilità di innestare diverse chiamate, come nell'ultimo esempio d'uso che riporto.
#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
#include <boost/bimap.hpp>
using namespace std;
class A {
int value_;
public:
A(int value) : value_(value) {
}
void print() {
cout << "Value is: " << value_ << endl;
}
};
void doSomething(int a, int b) {
if (a == b) {
cout << "done" << endl;
}
}
int main() {
int numbers[] = {10, 20, 30, 40, 50, 10};
int cx = count_if(numbers, numbers + 6, bind1st(equal_to<int>(), 10));
cout << cx << endl;
cx = count_if(numbers, numbers + 6, boost::bind(equal_to<int>(), _1, 10));
cout << cx << endl;
for_each(numbers, numbers + 6, boost::bind(&doSomething, _1, 10));
vector<A> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
for (vector<A>::iterator it = v.begin(); it != v.end(); ++it) {
it->print();
}
cout << "for_each:" << endl;
for_each(v.begin(), v.end(), mem_fun_ref(&A::print));
cout << "for_each w/ boost::bind:" << endl;
for_each(v.begin(), v.end(), boost::bind(&A::print, _1));
cout << "count w/ nested boost::bind:" << endl;
int count = count_if(numbers, numbers + 6,
boost::bind(logical_and<bool>(),
boost::bind(greater<int>(), _1, 15),
boost::bind(less_equal<int>(), _1, 40)));
cout << count << endl;
}
Nessun commento:
Posta un commento