2009-07-21 15 views
7

Je suis confus quant à ce que boost :: bind fait lorsque nous nous lions à des variables membres. Avec la liaison à la fonction membre, nous créons essentiellement un objet fonction, puis l'appelons les arguments fournis ou retardés et substitués via des espaces réservés.Liaison à une variable membre

Mais qu'est-ce que cette expression ne dans les coulisses:

boost::bind(&std::pair::second, _1); 

Ce qui est substitué en place de l'espace réservé _1?

Je trouve cela tout en lisant cet exemple d'un article sur boost :: bind:

void print_string(const std::string& s) { 
    std::cout << s << '\n'; 
} 

std::map<int,std::string> my_map; 
my_map[0]="Boost"; 
my_map[1]="Bind"; 

std::for_each(
    my_map.begin(), 
    my_map.end(), 
    boost::bind(&print_string, boost::bind(
     &std::map<int,std::string>::value_type::second,_1))); 

source

Répondre

4

Dans les coulisses, il utilise un pointeur de membre et de l'appliquer au passé dans argument. Il est assez complexe dans le contexte de binds, voici donc un exemple simple de pointeur sur l'utilisation du membre:

int main() 
{ 
    std::pair< int, int > p1 = make_pair(1, 2); 
    std::pair< int, int > p2 = make_pair(2, 4); 
    int std::pair<int,int>::*ptr = &std::pair<int,int>::second; // pointer to second member 

    std::cout << p1.*ptr << std::endl; // 2 dereference pointer to member 
    std::cout << p2.*ptr << std::endl; // 4 dereference pointer to member 
} 

Dans les coulisses se lier est la composition de différents appels. Le foncteur résultant prend la déréférence de std :: map <> :: iterator (de type std :: pair < const type_clé, type_valeur>). Cela est transmis à la liaison interne, qui déréférence le pointeur membre, renvoyant ainsi (*it).second à la liaison externe qui transmet cette valeur à la méthode print_string pour l'appel final: print_string((*it).second).

(*it) est en fait le _1 vous avez posé des questions sur. Tous les _# sont des espaces réservés, c'est-à-dire que le résultat de bind sera un foncteur qui prendra autant d'arguments que différents espaces réservés existent dans l'ordre défini par le nombre d'espaces réservés. Dans l'exemple que vous avez donné, le foncteur résultant prend un seul argument _1.

2
boost::bind(&std::pair<U,V>::second, _1); 

est fonctionnellement équivalent à

std::pair<U,V> p -> p.second 

ie. c'est une fonction (objet) qui mappe un pair<U,V> à son membre second.