2010-07-11 59 views
9

我有这样的循环:转换for循环一个std :: for_each的

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

应该有for_each工作,不应该吗?我应该改变什么?

+1

如果你愿意用升压,有优秀的foreach执行,BOOST_FOREACH – Anycorn 2010-07-11 02:09:05

回答

8

for_each需要某种可调用的实体。为了在另一个对象上调用成员函数,你需要使用mem_fun,它包装了成员函数,以便它可以像普通函数一样被调用,然后你需要将它绑定到它应该被调用的对象实例上bind1st

std::for_each(items.begin(), items.end(), 
    std::bind1st(std::mem_fun(&ClassName::add), &investigators)); 

另一种选择是使用更现代bind,你的实现可以在stdstd::tr1命名空间提供(如果没有,你可以使用the implementation from Boost):

using std::placeholders::_1; 

std::for_each(items.begin(), items.end(), 
    std::bind(&ClassName::add, &investigators, _1); 
+0

这就是我一直在寻找。谢谢。 – Max 2010-07-11 01:04:25

2

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。

1

如果你有lambda的话你可以做

for_each(items.begin(), items.end(), 
     [&](const ItemPtr& it) {investigators.addToLeaderInventory(it);});