2010-09-20 3 views
7

Je suis en train de comprendre l'exemple suivant, qui est similaire (mais pas égal) à celui affiché plus tôt sur le SO Help understanding boost::bind placeholder arguments:Boost.Bind - comprendre des espaces réservés

#include <boost/bind.hpp> 
#include <functional> 

struct X { 
    int value; 
}; 

int main() {  
    X a = { 1 }; 
    X b = { 2 }; 

    boost::bind(std::less<int>(), 
     boost::bind(&X::value, _1), 
     boost::bind(&X::value, _2)) 
    (a, b); 
} 

Comment est-ce possible, que la La fonction de liaison la plus externe sait qu'elle doit passer le premier argument à la deuxième liaison (qui attend _1) et le deuxième argument à la troisième liaison (qui attend _2)? La façon dont je vois ceci est que les liants internes sont évalués en premier, de sorte qu'ils deviennent deux objets fonctionnels unaires, qui sont ensuite passés au liant de l'objet less<int>. Et lorsque l'objet fonctionnel nouvellement créé est appelé avec deux objets, a va à la première liaison interne, et b va à la seconde. Si j'avais raison, nous utiliserions deux fois _1. Je dois avoir tort. Je vais répéter ma question une fois de plus pour clarifier mon problème: comment le classeur externe sait-il quel espace réservé a été utilisé dans quel classeur?

Répondre

7

Les arguments sont compressés en tuple (a, b) et transmis aux foncteurs. alors le foncteur interne décide quel élément de tuple il a besoin, par ex. essayez:

boost::bind(&X::value, _1)(a,b) 
boost::bind(&X::value, _2)(a,b) 

Plus généralement, chaque valeur, peu importe si elle est constante/référence/espace réservé est représenté comme foncteur qui prend valeur tuple argument et retourne. Maintenant, je ne suis pas sûr à cent pour cent que c'est ainsi que la liaison le fait. Cependant, c'est ainsi que Phoenix met en œuvre ses fonctionnalités. Si vous essayez de comprendre le mécanisme d'implémentation de bind/lambda, regardez Phoenix, il est très extensible et possède une excellente documentation.

+0

ok, je comprends. Mais que se passe-t-il si l'un des arguments liés n'est pas un classeur, par ex. valeur costante? Je veux dire: boost :: bind (std :: less (), boost :: bind (& X :: valeur, _1), 10) (a); Comment sait-il à quel argument il doit assigner le tuple généré? –

+1

@Mar J'ai mis à jour ma réponse, n'hésitez pas à regarder – Anycorn

Questions connexes