简体   繁体   English

将for循环转换为std :: for_each

[英]converting a for loop to a std::for_each

I've got this for loop: 我有这个for循环:

    std::vector<itemPtr>::iterator it;
    for(it=items.begin(); it!=items.end(); ++it)
    {
        investigators.addToLeaderInventory(*it);
    }

I'd like to convert it to something like this: 我想把它转换成这样的东西:

std::for_each(items.begin(), items.end(), investigators.addToLeaderInventory);

However, that line doesn't compile. 但是,该行无法编译。 g++ shows me this: 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)]

Hard to read, to say the least. 至少可以说,难以阅读。 I imagine the solution is pretty simple, but I can't figure out what g++ is complaining about. 我想解决方案非常简单,但我无法弄清楚g ++在抱怨什么。 The signature of investigators.addToLeaderInventory() is this: investigators.addToLeaderInventory()的签名是这样的:

void ClassName::addToLeaderInventory(itemPtr item);

which should work with a for_each , shouldn't it? 哪个应该与for_each一起使用,不应该吗? What should I change? 我应该改变什么?

for_each takes a callable entity of some kind. for_each采用某种可调用的实体。 In order to call a member function on another object, you need to use mem_fun , which wraps the member function so that it can be called like an ordinary function, then you need to bind it to the object instance on which it should be called using bind1st : 为了在另一个对象上调用成员函数,你需要使用mem_fun ,它包装成员函数,以便可以像普通函数一样调用它,然后你需要将它绑定到应该使用它调用它的对象实例bind1st

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

Another option is to use the more modern bind , which your implementation may provide in the std or std::tr1 namespace (if it doesn't, you can use the implementation from Boost ): 另一种选择是使用更现代的bind ,您的实现可以在stdstd::tr1命名空间中提供(如果没有,您可以使用Boost中的实现 ):

using std::placeholders::_1;

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

C++ can't bind an object and a method together into a single callable "function". C ++不能将对象和方法绑定到一个可调用的“函数”中。 You have to do the binding explicitly, either via a object with a custom operator() ... 你必须通过一个带有自定义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));

...or using a library such as Boost.Bind. ...或使用Boost.Bind等库。

If you have lambdas then you could do 如果你有lambdas那么你可以做

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM