std::find_if

Fórumok

Sziasztok !

Egy egyszeru kodot kerestem egy value keresere egy map-ben es a kovetkezot talaltam :


int main()
{
typedef std::map my_map;

my_map m;
m.insert(std::make_pair(0, "zero"));
m.insert(std::make_pair(1, "one"));
m.insert(std::make_pair(2, "two"));

const std::string s("one");
const my_map::const_iterator it = std::find_if(m.begin(), m.end(), boost::bind(&my_map::value_type::second, _1) == s);
}

Erti valaki, hogy a find_if -es sorban a legutolso argot miert fogadja el a fordito?

Gabor

Hozzászólások

Nézd meg a boost::bind dokumentációját, illetve a boost::lamba-ét.

Tippre (nem futottam át) azt csinálja, hogy a boost::bind függvény visszatérési értéke egy olyan objektum, amelynek van egy olyan nem bool típust visszaadó == operátora, amely megvalósítja a find_if-hez szükséges interface-t.

Szerencsére a C++11-ben már van lambda :-)

Jo regi ez a kerdes, de megerdemel egy valaszt mert szerintem sokat lehet belole tanulni.

Ket mechanizmus van itt hasznalva

1. A boost::bind-ot meg lehet hivni member fuggveny pointer (ez a tipikus felhasznalasi mod) helyett sima adattagra mutato pointerrel is. Ez a bind() fuggveny olyan funktort ad vissza, amit ha egy this pointerrel (vagy annak megfelelo referenciaval vagy smart pointerrel) hivsz meg, akkor visszaadja az adott adattag erteket. Ez klassz dolog, de csak reszben magyarazza meg a torteneseket.

2. Az erdekesebb resz (mar amennyiben nem alszik maris mindenki ;) ): erre a funktorra van definialva egy halom operator (negacio es a relacios operatorok), amiknek a visszateresi erteke nem bool, hanem egy bool visszeteresi erteku funktor (un. "nested bind").

Ezt azt jelenti, hogy a:


boost::bind(&my_map::value_type::second, _1) == s

nem bool-ra ertekelodik ki, hanem egy olyan "nested bind"-ra, ami tartalmazza a baloldali kifejezes eredmenyet es a jobboldalt (s) egy objektumba csomagolva (boost::_bi::value). Ez a bind expression hivas eseten delegalja a hivast a becsomagolt objektumba, az eredmenyt osszehasonlitja a jobboldali objektummal (illetve annak egy masolataval) es az osszehonlitas eredmenyet dobja vissza a hivonak.

Ami valojaban tortenik, az talan ennel egy picit kacifantosabb, de a lenyeg gondolom viszonylag ertheto. Annyit meg erdemes megjegyezni, hogy a c++11-ben levo std::bind is meg tudja csinalni a trukk elso reszet, de a relacios operatorok nincsenek definialva a visszaadott objektumra, igy a trukk masodik reszen szerintem elhasal a standard konyvtar.