2010-06-01 6 views
0

J'ai une autre question sur les fonctions de référence. Par exemple, je dois cette définition:Travailler avec les références de fonction

typedef boost::function<bool (Entity &handle)> behaviorRef; 
std::map< std::string, ptr_vector<behaviorRef> > eventAssociation; 

La première question est la suivante: comment insérer des valeurs dans un tel objet de la carte?

J'ai essayé:

eventAssociation.insert(std::pair< std::string, ptr_vector<behaviorRef> >(eventType, ptr_vector<behaviorRef>(callback))); 

Mais l'erreur:

no matching function for call to ‘boost::ptr_vector<boost::function<bool(Entity&)> >::push_back(Entity::behaviorRef&)’ 

Et j'undersatnd, mais ne peut rendre le code réalisable.

La deuxième question est comment appeler de telles fonctions? Par exemple, j'ai un objet de behaviorRef, comment l'appeler avec boost :: bind avec mes propres valeurs?

+1

Comme astuce, vous pouvez utiliser 'std :: make_pair()' au lieu de construire la paire directement; Cela vous évite d'avoir à écrire les paramètres du template de la paire. –

+0

@ james-mcnellis merci pour le pourboire! – Ockonal

Répondre

2

PARTIE 1

Il n'y a pas besoin d'utiliser un ptr_vector. boost::function a une valeur sémantique, donc peut être stocké dans un conteneur standard. Donc, ce qui suit devrait fonctionner:

typedef boost::function<bool (Entity &handle)> behaviorRef; 
std::map< std::string, std::vector<behaviorRef> > eventAssociation; 

eventAssociation.insert(std::make_pair(eventType, vector<behaviorRef>(1, callback))); 

Notez les deux arguments au constructeur vector.

Si vous avez besoin d'un ptr_vector (parce que vous utilisiez un type noncopyable), vous auriez besoin de quelque chose comme ce qui suit, car ptr_vector n'a pas de constructeur qui renseigne le vecteur:

ptr_vector<behaviorRef> behaviours; 
behaviours.push_back(new behaviourRef(callback)); 
eventAssociation.insert(std::make_pair(eventType, behaviours)); 

PARTIE 2

Il n'est pas nécessaire d'utiliser boost::bind pour appeler la fonction (bien que vous puissiez l'utiliser en premier lieu).La syntaxe pour l'appeler est la même que pour une fonction normale:

behaviourRef behaviour; 
Entity entity; 
bool result = behaviour(entity); 
+0

Merci, mais je ne comprends pas pourquoi passez-vous deux argmuments au fichier std :: vector? – Ockonal

+2

@Ockonal: Le premier argument est la taille du vecteur (c'est-à-dire, le nombre d'objets qu'il contient initialement), le second est un objet qui sera utilisé pour copier-construire les objets initialement créés. Par exemple: 'vector (10, some_foo)' crée un vecteur contenant 10 clones de some_foo –

+0

Ok, super! Merci. – Ockonal

3

Première question:

ptr_vector<Foo> contient des pointeurs vers Foo. Donc, si vous avez besoin d'utiliser ptr_vector (peut-être parce que vos objets de fonction sont chers à copier), vous devez pousser les pointeurs vers behaviorRef.

deuxième question, la première partie:

Une behaviorRef est appelée avec la même syntaxe qu'une fonction bool(Entity&):

// Somehow get an Entity and a behaviorRef 
Entity some_entity = ...; 
behaviorRef some_behavior = ...; 

// Call the behaviorRef 
bool result = some_behavior(some_entity); 

deuxième question, la deuxième partie:

A behaviorRef peut être utilisé avec boost :: bind de la même manière qu'un autre objet fonction:

// Somehow get an Entity and a behaviorRef 
Entity some_entity = ...; 
behaviorRef some_behavior = ...; 

// Make a new function object, bound to some_entity 
boost::function<bool()> bound_behavior = boost::bind(some_behavior, some_entity); 

// Call the bound function. 
bool result = bound_behavior(); 
+0

Votre réponse à la deuxième question est excellente, merci! C'est dommage que je ne puisse pas marquer deux réponses. – Ockonal