2009-10-26 26 views
5

करने में सक्षम यह एक समय हो गया है के बाद से दृश्य स्टूडियो एक foreach विस्तार से काम करता है किकैसे एक वर्ग foreach

तरह
vector<int> v(3) 
for each (int i in v) { 
    printf("%d\n",i); 
} 

मुझे पता है कि कैसे किसी भी वर्ग foreach उपयोग करने में सक्षम बनाना चाहते के लिए समर्थन जोड़ा लिखने के लिए। क्या मुझे कुछ इंटरफेस लागू करने की ज़रूरत है?

+0

एमएस संकलक समर्थित कभी नहीं anyting उपयोग करने के लिए IEnumerable वारिस चाहिए। मुझे लगता है कि आप किसी अन्य भाषा के बारे में बात कर रहे हैं। सी#? यदि ऐसा है, तो आपको अपने प्रश्न को पुनः प्राप्त करने की आवश्यकता है। – AnT

+3

http://msdn.microsoft.com/en-us/library/ms177202%28VS.80%29.aspx – stelonix

+2

शायद सी ++ टैग एक वीसी ++ टैग होना चाहिए। यह निश्चित रूप से एक मानक सी ++ सवाल नहीं है। – MAK

उत्तर

10

for each कुलपति ++ में बयान, जब एक गैर-प्रबंधित वर्ग पर इस्तेमाल किया:

for (auto iter = xs.begin(), end = xs.end(); iter != end; ++iter) 
{ 
    T x = *iter; 
} 

कहाँ auto मतलब है चर के प्रकार से स्वचालित रूप से निष्कर्ष निकाला है:

for each (T x in xs) 
{ 
    ... 
} 

इस के लिए बस वाक्यात्मक चीनी है प्रारंभकर्ता का प्रकार।

दूसरे शब्दों में, आपको begin() और end() अपनी कक्षा पर विधियों को प्रदान करने की आवश्यकता है जो इसके लिए प्रारंभ और अंत इनपुट इटरेटर्स लौटाएंगे।

यहाँ वर्ग का एक उदाहरण है कि एक istream लपेटता है और आप इसे में सभी लाइनों पर चीज़ों को दोहरा सकते है:

#include <istream> 
#include <iostream> 
#include <fstream> 
#include <string> 


class lines 
{ 
public: 

    class line_iterator 
    { 
    public: 

     line_iterator() : in(0) 
     { 
     } 

     line_iterator(std::istream& in) : in(&in) 
     { 
      ++*this; 
     } 

     line_iterator& operator++() 
     { 
      getline(*in, line); 
      return *this; 
     } 

     line_iterator operator++ (int) 
     { 
      line_iterator result = *this; 
      ++*this; 
      return result; 
     } 

     const std::string& operator*() const 
     { 
      return line; 
     } 

     const std::string& operator->() const 
     { 
      return line; 
     } 

     friend bool operator== (const line_iterator& lhs, const line_iterator& rhs) 
     { 
      return (lhs.in == rhs.in) || 
        (lhs.in == 0 && rhs.in->eof()) || 
        (rhs.in == 0 && lhs.in->eof()); 
     } 

     friend bool operator!= (const line_iterator& lhs, const line_iterator& rhs) 
     { 
      return !(lhs == rhs); 
     } 

    private: 

     std::istream* const in; 
     std::string line; 
    }; 


    lines(std::istream& in) : in(in) 
    { 
    } 

    line_iterator begin() const 
    { 
     return line_iterator(in); 
    } 

    line_iterator end() const 
    { 
     return line_iterator(); 
    } 

private: 

    std::istream& in; 
}; 


int main() 
{ 
    std::ifstream f(__FILE__); 
    for each (std::string line in lines(f)) 
    { 
     std::cout << line << std::endl; 
    } 
} 

नोट वास्तव में for each द्वारा आवश्यक न्यूनतम की तुलना में कुछ बड़ा है कि line_iterator के कार्यान्वयन; तथापि, यह कम से कम कार्यान्वयन कि इनपुट इटरेटर आवश्यकताओं के अनुरूप है, और इस तरह इस वर्ग के भी सभी एसटीएल एल्गोरिदम कि इनपुट iterators पर काम के साथ प्रयोग करने योग्य है, इस तरह के रूप std::for_each, std::find आदि

+0

क्या आप उन वर्गों को लागू करने वाले वर्ग का सबसे सरल उदाहरण दे सकते हैं जो संकलित करेंगे? बस विधियों के रिटर्न प्रकारों और जो कुछ भी मुझे याद आ रहा है, उसे जानने की आवश्यकता है, क्योंकि मैं एक साधारण वर्ग – stelonix

+0

के साथ संकलित करने में सक्षम नहीं हूं, आपको इसे शुरू करने और इसे समाप्त करने की आवश्यकता है। – GManNickG

+0

उदाहरण शामिल करने के लिए अद्यतन उत्तर। वास्तविक रिटर्न प्रकार कोई फर्क नहीं पड़ता, जब तक कि वे प्रत्येक ऑपरेशन का समर्थन करते हैं जो 'प्रत्येक के लिए' के ​​विस्तारित विस्तार से निहित हैं। –

0

foreach सी ++ भाषा का हिस्सा नहीं है जहां तक ​​मुझे पता है। हालांकि यह सी # में है। साथ ही, मुझे लगता है कि एसटीएल और/या बूस्ट की एक foreach विधि है। शायद आप उस बारे में सोच रहे हैं?

+1

मुझे पता है कि यह भाषा का हिस्सा नहीं है और मुझे यह भी पता है कि एसटीएल और बूस्ट में एक फोरच है। हालांकि, विजुअल स्टूडियो कंपाइलर एक कंपाइलर एक्सटेंशन के रूप में दिखाए गए तरीके से foreach का समर्थन करता है, और मैं यह जानना चाहता हूं कि कक्षाएं कैसे काम करती हैं। – stelonix

+0

आह ठीक है, गलतफहमी के लिए खेद है। –

+0

गलतफहमी के लिए डाउनवॉटेड, फिर इसके लिए क्षमा मांगना? किसी को डाउनवॉटिंग स्प्री पर चला जाता है। –

1

आप इस

का उपयोग कर सकते है std::for_each

+0

+1 जब भी संभव हो गैर-मानक एक्सटेंशन के मानकों को पसंद करें। –

+3

'std :: for_each' वास्तव में एक प्रतिस्थापन नहीं है क्योंकि यह आपको प्रत्येक पुनरावृत्ति इनलाइन के लिए निष्पादित करने के लिए कोड के ब्लॉक को निर्दिष्ट नहीं करने देता है। प्रैक्टिस में, मैं इस कारण से लगभग 'std :: for_each' का उपयोग नहीं करता - यह इटेटर के साथ एक अच्छा पुराना 'लूप' लिखना आसान है। प्रत्येक के लिए 'के लिए '- यह निश्चित रूप से पोर्टेबल कोड में कोई स्थान नहीं है, लेकिन सभी कोड अर्थपूर्ण रूप से पोर्टेबल नहीं है। यदि आपका आवेदन पहले ही एमएफसी या एटीएल का उपयोग कर लिखा गया है, तो आप वैसे भी वीसी ++ के साथ फंस गए हैं, और इसके भाषा एक्सटेंशन का उपयोग करने में कुछ भी गलत नहीं है। –

+0

ठीक है, अगर पोर्टेबिलिटी की आवश्यकता नहीं है, तो मैं पूल में लैम्ब्डा फ़ंक्शंस फेंकना चाहता हूं और इस जवाब को वोट देना चाहता हूं। वे कुछ कंपाइलर्स द्वारा अब या बहुत जल्द ही लागू किए जाने के लिए बाध्य हैं, और वे वास्तव में बेहतर समाधान के लिए 'std :: for_each 'बनाएंगे, क्योंकि वे मानक बन जाएंगे (उम्मीद है कि) _all_ compilers अंततः समर्थन करेंगे। – sbi

-2

आपका वर्ग कि सी ++ कोड के लिए की तरह foreach