2010-06-01 2 views
0

У меня есть еще один вопрос об использовании функций. Например, у меня есть такое определение:Работа с ссылками на функции

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

Первый вопрос: как вставить значения в такой объект карты?

Я пробовал:

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

Но ошибка:

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

И я undersatnd его, но не может сделать работоспособный код.

Второй вопрос - как назвать такие функции? Например, у меня есть один объект behaviorRef, как его называть boost :: bind с передачей моих собственных значений?

+1

В качестве подсказки вы можете использовать 'std :: make_pair()' вместо прямого создания пары; это позволяет избежать необходимости записывать параметры шаблона пары. –

+0

@ james-mcnellis спасибо за подсказку! – Ockonal

ответ

2

ЧАСТЬ 1

Там нет необходимости использовать ptr_vector. boost::function имеет семантику значений, поэтому ее можно хранить в стандартном контейнере. Таким образом, следующее должно работать:

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

Обратите внимание на два аргумента vector конструктора.

Если вы сделали нужен ptr_vector (потому что вы использовали noncopyable тип), вам нужно что-то вроде следующего, так как ptr_vector не имеет конструктор, который заполнит вектор:

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

ЧАСТЬ 2

Нет необходимости использовать boost::bind для вызова функции (хотя вы можете использовать ее, чтобы сделать ее в первую очередь).Синтаксис его вызова такой же, как и для нормальной функции:

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

Спасибо, но я не понимаю, почему вы передаете два аргумента в std :: vector? – Ockonal

+2

@Ockonal: первый аргумент - это размер вектора (т. Е. Номер объекта, который он изначально хранит), второй - это объект, который будет использоваться для копирования-построения первоначально созданных объектов. Например: 'vector (10, some_foo)' создает вектор, содержащий 10 клонов some_foo –

+0

Хорошо, отлично! Благодарю. – Ockonal

3

Первый вопрос:

ptr_vector<Foo> содержит указатели на Foo. Поэтому, если вам нужно использовать ptr_vector (возможно, потому, что объекты вашей функции дорого копируются), вы должны указывать push_back на поведениеRef.

Второй вопрос, часть первая:

behaviorRef вызывается с тем же синтаксисом, чем bool(Entity&) функции:

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

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

Второй вопрос, часть вторая:

behaviorRef может использоваться с boost :: bind так же, как и другой объект функции:

// 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

Ваш ответ на второй вопрос большой, спасибо! Жаль, что я не могу отметить два ответа. – Ockonal

Смежные вопросы