views:

71

answers:

2

Hello, I have another one question about functions reference. For example, I have such definition:

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

The first question is: how to insert values into such map object?

I tried:

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

But the error:

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

And I undersatnd it, but can't make workable code.

The second question is how to call such functions? For example, I have one object of behaviorRef, how to call it with boost::bind with passing my own values?

+3  A: 

First question:

ptr_vector<Foo> contains pointers to Foo. So if you need to use ptr_vector (maybe because your function objects are expensive to copy), you have to push_back pointers to behaviorRef.

Second question, part one:

A behaviorRef is called with the same syntax than a bool(Entity&) function:

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

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

Second question, part two:

A behaviorRef can be used with boost::bind in the same way than another function object:

// 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();
Éric Malenfant
Your answer for second question is great, thank you! It's a pity that I can't mark two answers.
Ockonal
+2  A: 

PART 1

There's no need to use a ptr_vector. boost::function has value semantics, so can be stored in a standard container. So the following should work:

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)));

Note the two arguments to the vector constructor.

If you did need a ptr_vector (because you were using a noncopyable type), you'd need something like the following, since ptr_vector doesn't have a constructor that populates the vector:

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

PART 2

There's no need to use boost::bind for calling the function (although you can use it to make it in the first place). The syntax for calling it is the same as for a normal function:

behaviourRef behaviour;
Entity entity;
bool result = behaviour(entity);
Mike Seymour
Thanks, but I can't understand why do you passing two argmuments to the std::vector?
Ockonal
@Ockonal: The first argument is the size of the vector (i.e., the number of object it initially holds), the second one is an object that will be used to copy-construct the initially created objects. For example: `vector<Foo>(10, some_foo)` creates a vector containing 10 clones of some_foo
Éric Malenfant
Ok, great! Thanks.
Ockonal