2012-02-06 17 views
9

मैं कॉलबैक फ़ंक्शंस के एक सेट पर फिर से चल रहा हूं। कार्यों को पुनरावृत्ति के दौरान बुलाया जाता है और कार्यों के सेट के वास्तविक कंटेनर में कठोर परिवर्तन हो सकता है।एक बदलते कंटेनर को इटरेट करना

क्या मैं अब कर रहा हूँ है:

  1. मूल सेट प्रति अधिक
  2. पुनरावृति की एक प्रतिलिपि बनाने, लेकिन प्रत्येक तत्व के लिए जाँच करें कि क्या यह अभी भी मूल सेट

जाँच में मौजूद है प्रत्येक तत्व के अस्तित्व के लिए सुपर गतिशील है, लेकिन यह भी धीमा लगता है।

क्या इस मामले से निपटने के लिए अन्य प्रस्ताव हैं?

संपादित करें:

// => i = event id 
    template <class Param> 
    void dispatchEvent(int i, Param param) { 

     EventReceiverSet processingNow; 

     const EventReceiverSet& eventReceiverSet = eventReceiverSets[i]; 
     std::copy(eventReceiverSet.begin(), eventReceiverSet.end(), std::inserter(processingNow, processingNow.begin())); 

     while (!processingNow.empty()) { 
      EventReceiverSet::iterator it = processingNow.begin(); 
      IFunction<>* function = it->getIFunction(); /// get function before removing iterator 
      processingNow.erase(it); 

      // is EventReceiver still valid? (may have been removed from original set) 
      if (eventReceiverSet.find(ERWrapper(function)) == eventReceiverSet.end()) continue; // not found 

      function->call(param); 
     } 
    }; 
+0

तक "सेट" आप क्या मतलब है 'std :: सेट <>'? यदि नहीं, वास्तविक कंटेनर प्रकार क्या है? – ildjarn

+0

ठीक है, मैं यह सामान्य छोड़ना चाहता था, लेकिन हाँ, यह एक std :: set –

उत्तर

4

दो बुनियादी दृष्टिकोण मन के लिए आते हैं: यहां वास्तविक कोड है

  1. के लिए एक कतार पर एक कार्य आधारित दृष्टिकोण (संग्रह बंद कर दिया, धक्का कार्यों के साथ उपयोग करें प्रत्येक तत्व, फिर काम करने के लिए सभी पार्टियों को छोड़ दें और पूरा होने तक प्रतीक्षा करें)। कार्य को वास्तव में शुरू होने पर आपको अभी भी एक चेक की आवश्यकता होगी कि वर्तमान कार्य के लिए तत्व संग्रह में मौजूद/वर्तमान में मौजूद है या नहीं।

    • इस

  2. (विशेष रूप से लेखकों की तुलना में अधिक पाठकों के साथ) जाँच करता है, जो आमतौर पर fullblown आपसी बहिष्करण से त्वरित है के लिए पाठक लेखक ताले का लाभ उठाने सकता है एक समवर्ती डेटा संरचना का उपयोग करें (मेरा मतलब है , एक जो स्पष्ट लॉकिंग के बिना बहुप्रचारित पहुंच के लिए उपयुक्त है)। (शीघ्र ही लिंक जोड़ने)

3

यह करने के लिए एक तरीका होता है: निम्नलिखित पुस्तकालयों समवर्ती डेटा संरचनाओं के कार्यान्वयन शामिल दो चरणों में: सबसे पहले, मूल सेट के माध्यम से जाओ, और बनाओ कार्रवाई वस्तुओं का एक सेट। फिर कार्रवाई वस्तुओं के सेट के माध्यम से जाओ, और उन्हें मूल सेट पर लागू करें।

एक एक्शन आइटम सबक्लास के साथ एक बेस क्लास है। प्रत्येक उपवर्ग एक सेट में ले जाता है, और उस पर एक विशिष्ट कार्रवाई निष्पादित करता है, उदाहरण के लिए:

struct set_action { 
    virtual void act(std::set<int> mySet) const; 
}; 
class del_action : public set_action { 
private: 
    int item; 
public: 
    del_action(int _item) : item(_item) {} 
    virtual void act(std::set<int> mySet) const { 
     // delete item from set 
    } 
}; 
class upd_action : public set_action { 
private: 
    int from, to; 
public: 
    upd_action(int _from, int _to) : from(_from), to(_to) {} 
    virtual void act(std::set<int> mySet) const { 
     // delete [from], insert [to] 
    } 
}; 

अब आप पहले पास में set_action* रों का एक संग्रह बना सकते हैं, और उन्हें दूसरे पास में चलाते हैं।

3

set संरचना को परिवर्तित करने वाले ऑपरेशंस insert() और erase() हैं।

पुनरावृत्त करते समय, पर उत्परिवर्तक संचालन द्वारा लौटाए गए इटरेटर का उपयोग करके विचार करें।

it = myset.erase(it); 

http://www.cplusplus.com/reference/stl/set/erase/

+0

आपके द्वारा उद्धृत लिंक कहता है: शून्य सेट :: मिटाएं (पुनरावृत्ति स्थिति); –

संबंधित मुद्दे