2010-07-11 11 views
9

पाश के लिए एक परिवर्तित मैं पाश के लिए यह मिल गया है:एक एसटीडी करने के लिए :: 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); 

हालांकि, उस रेखा संकलित नहीं है। जी ++ मुझे यह दिखाता है:

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

कम से कम कहने के लिए पढ़ने के लिए मुश्किल है। मुझे लगता है कि समाधान बहुत आसान है, लेकिन मैं यह नहीं समझ सकता कि जी ++ किस बारे में शिकायत कर रहा है।

void ClassName::addToLeaderInventory(itemPtr item); 

जो एक for_each साथ काम करना चाहिए, ऐसा नहीं होना चाहिए: investigators.addToLeaderInventory() के हस्ताक्षर है? मुझे क्या बदलना चाहिए?

+1

अगर आप को बढ़ावा देने का उपयोग करने को तैयार हैं, वहाँ उत्कृष्ट foreach कार्यान्वयन, BOOST_FOREACH – Anycorn

उत्तर

8

for_each किसी तरह की एक प्रतिदेय इकाई लेता है। किसी अन्य ऑब्जेक्ट पर किसी सदस्य फ़ंक्शन को कॉल करने के लिए, आपको mem_fun का उपयोग करने की आवश्यकता है, जो सदस्य फ़ंक्शन को लपेटता है ताकि इसे सामान्य फ़ंक्शन की तरह कहा जा सके, फिर आपको ऑब्जेक्ट इंस्टेंस पर बाध्य करने की आवश्यकता है जिस पर इसे उपयोग करना चाहिए bind1st:

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

एक अन्य विकल्प और अधिक आधुनिक bind, जो आपके कार्यान्वयन std या std::tr1 नाम स्थान में उपलब्ध करा सकता है (यदि ऐसा नहीं होता है, तो आप the implementation from Boost उपयोग कर सकते हैं) का उपयोग करने के लिए है:

using std::placeholders::_1; 

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

यह मैं के लिए क्या देख रहा था है। धन्यवाद। – Max

2

सी ++ एक भी प्रतिदेय "समारोह" में एक साथ एक वस्तु और एक विधि के लिए बाध्य नहीं कर सकते। आप एक कस्टम 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

यदि आपके पास भेड़ का बच्चा है तो तुम कर सकते हो

for_each(items.begin(), items.end(), 
     [&](const ItemPtr& it) {investigators.addToLeaderInventory(it);}); 
संबंधित मुद्दे