У меня есть это для цикла:
std::vector<itemPtr>::iterator it;
for(it=items.begin(); it!=items.end(); ++it)
{
investigators.addToLeaderInventory(*it);
}
Я хотел бы преобразовать его во что-то вроде этого:
std::for_each(items.begin(), items.end(), investigators.addToLeaderInventory);
Однако та строка не компилирует. g ++ показывает мне это:
error: no matching function for call to
‘for_each(__gnu_cxx::__normal_iterator<std::tr1::shared_ptr<yarl::item::Item>*,
std::vector<std::tr1::shared_ptr<yarl::item::Item>,
std::allocator<std::tr1::shared_ptr<yarl::item::Item> > > >,
__gnu_cxx::__normal_iterator<std::tr1::shared_ptr<yarl::item::Item>*,
std::vector<std::tr1::shared_ptr<yarl::item::Item>,
std::allocator<std::tr1::shared_ptr<yarl::item::Item> > > >, <unresolved overloaded
function type>)’
/usr/include/c++/4.4/bits/stl_algo.h:4194: note: candidates are: _Funct
std::for_each(_IIter, _IIter, _Funct) [with _IIter =
__gnu_cxx::__normal_iterator<std::tr1::shared_ptr<yarl::item::Item>*,
std::vector<std::tr1::shared_ptr<yarl::item::Item>,
std::allocator<std::tr1::shared_ptr<yarl::item::Item> > > >, _Funct = void
(yarl::party::Party::*)(yarl::itemPtr)]
Трудно читать, по меньшей мере. Я предполагаю, что решение довольно просто, но я не могу выяснить то, на что жалуется g ++. Подпись investigators.addToLeaderInventory()
это:
void ClassName::addToLeaderInventory(itemPtr item);
который должен работать с a for_each
, не был должен это? Что я должен изменить?
for_each
принимает какую-либо вызываемую сущность. Чтобы вызвать функцию-член на другом объекте, нужно использовать mem_fun
, который оборачивает функцию-член так, что ее можно вызвать как обычную функцию, затем нужно привязать ее к экземпляру объекта, на котором она должна быть вызвана, используя bind1st
:
std::for_each(items.begin(), items.end(),
std::bind1st(std::mem_fun(&ClassName::add), &investigators));
Другой вариант - использовать более современный bind
, который ваша реализация может предоставить в пространстве имен std
или std::tr1
(если это не так, вы можете использовать реализацию из Boost):
using std::placeholders::_1;
std::for_each(items.begin(), items.end(),
std::bind(&ClassName::add, &investigators, _1);
C ++ не может связать объект и метод вместе в одну вызываемую «функцию». Вы должны выполнить привязку явно, либо через объект с пользовательским operator ()
...
class AddToLeaderInventory {
public:
AddToLeaderInventory(party::Party& party) : party_(party) { }
void operator()(item::Item& i) { party_.addToLeaderInventory(i); }
private:
party::Party& party_;
};
...
std::for_each(items.begin(), items.end(), AddToLeaderInventory(investigators));
..., либо с помощью библиотеки, такой как Boost.Bind.
Если у вас есть лямбда-выражения, вы можете использовать
for_each(items.begin(), items.end(),
[&](const ItemPtr& it) {investigators.addToLeaderInventory(it);});