2012-09-26 14 views
5

मुझे कोड का यह छोटा स्निपेट मिला है। मुझे समझ में नहीं आता कि इस निर्माण का क्या अर्थ है। मुझे पता है कि कोड का यह स्निपेट इनपुट से संख्याओं को पढ़ता है और इसकी आवृत्ति को एक unordered_map में गिना जाता है। लेकिन [&] क्या है? और (int x) का अर्थ क्या है? input(cin) के लिए खड़ा क्या है? मेरा मतलब है "cin" कोष्ठक में? और input(cin) से खाली eof पैरामीटर के लिए it_each फिर से कैसे कर सकते हैं? मुझे इस पूरे निर्माण की समझ में नहीं आता है।यह सी ++/सी ++ 11 निर्माण का मतलब क्या है?

unordered_map<int,int> frequency; 
istream_iterator<int> input(cin); 
istream_iterator<int> eof; 

for_each(input, eof, [&] (int x) 
    { frequency[x]++; }); 
+6

नया सी ++ लैम्डा ऑपरेटर देखें! यह शानदार है – Minion91

उत्तर

6

istream_iterator आप iteratively एक istream से आइटम है, जो आप निर्माता करने के लिए पारित निकालने के लिए अनुमति देता है में बचत। eof ऑब्जेक्ट इस प्रकार समझाया गया है:

इस इटरेटर के लिए एक विशेष मान मौजूद है: स्ट्रीम ऑफ एंड स्ट्रीम; जब इटेटर इस मान पर सेट किया गया है तो या तो स्ट्रीम (ऑपरेटर शून्य * स्ट्रीम स्ट्रीम पर लागू होता है) के अंत तक पहुंच गया है या अपने डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग करके बनाया गया है (बिना किसी भी मूल_स्ट्रीम ऑब्जेक्ट के साथ इसे संबद्ध किए बिना)।

for_each एक लूप निर्माण है जो इटरेटर # 1 लेता है और इसे तब तक बढ़ाता है जब तक यह इटरेटर # 2 के बराबर न हो जाए। यहां यह इटेटरेटर लेता है जो मानक इनपुट cin को लपेटता है और इसे बढ़ाता है (जो वस्तुओं को निकालने का अनुवाद करता है) जब तक उपभोग करने के लिए कोई इनपुट नहीं होता है - इससे inputeof के बराबर की तुलना करता है और लूप समाप्त होता है।

निर्माण [&] (int x) { frequency[x]++; } एक anonymous function है; यह केवल इनलाइन कार्यों को लिखने का एक शॉर्टेंड तरीका है। लगभग एक ही प्रभाव तो संक्षेप में

unordered_map<int,int> frequency; // this NEEDS to be global now 
istream_iterator<int> input(cin); 
istream_iterator<int> eof; 

void consume(int x) { 
    frequency[x]++; 
} 

for_each(input, eof, consume); 

साथ प्राप्त किया जा सकता है: इस कोड को मानक इनपुट से पूर्णांकों पढ़ता है जब तक सभी उपलब्ध डेटा सेवन किया जाता है, एक नक्शा में प्रत्येक पूर्णांक की उपस्थिति आवृत्ति की गिनती रखते हुए।

+0

धन्यवाद, मुझे बस इतना ही चाहिए। – balent

+0

+1 अच्छा और संक्षिप्त स्पष्टीकरण! – Walter

1

यह एसटीएल std :: for_each (गैर सी ++ 11) इनपुट पुनरावृत्ति है जब तक EOF के बराबर है; प्रत्येक मूल्य

के लिए lambda [&] (int x) { frequency[x]++; } पर कॉल करना तो, यह कोड आईट्रीम में वर्णों की आवृत्ति की गणना करता है; उन्हें नक्शा

2

आपके प्रश्न के दो भाग हैं।

  1. पहला वाला स्ट्रीम इटरेटर से संबंधित है। std::istream_iterator<T> कुछ std::istream & s से बनाया गया है, और डेफरेंसिंग पर, यह { T x; s >> x; return x; } जैसा व्यवहार करता है। एक बार निष्कर्षण विफल हो जाने पर, इटरेटर एक डिफ़ॉल्ट-निर्मित इटरेटर के बराबर हो जाता है, जो "एंड" इटरेटर के रूप में कार्य करता है।

    स्ट्रीम इटरेटर आपको टोकन के कंटेनर के रूप में स्ट्रीम का इलाज करने की अनुमति देता है। उदाहरण के लिए:

    std::vector<int> v(std::istream_iterator<int>(std::cin), 
            std::istream_iterator<int>()); 
    
    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " ")); 
    
  2. सी ++ 11 द्वारा प्रस्तुत लैम्ब्डा भाव, जो गुमनाम कार्य या functors परिभाषित करते हैं (बंद कहा जाता है)।एक साधारण से एक इस तरह दिखता है:

    auto f = [](int a, int b) -> double { return double(a)/double(b); }; 
    
    auto q = f(1, 2); // q == 0.5 
    

    यह f सकता है एक साधारण, नि: शुल्क समारोह के रूप में लिखा गया है, लेकिन मुक्त समारोह नाम स्थान दायरे में या एक स्थानीय वर्ग के एक स्थिर सदस्य समारोह के रूप में प्रकट करने के लिए था। (वास्तव में लैम्ब्डा अभिव्यक्ति का प्रकार क्या है!) ध्यान दें कि लैम्ब्डा अभिव्यक्ति का प्रकार अनजान है, और केवल नए auto कीवर्ड के माध्यम से ही कब्जा कर लिया जा सकता है।

    जब वे जटिल कार्य ऑब्जेक्ट्स के रूप में कार्य करते हैं तो वेम्बडा अधिक उपयोगी हो जाते हैं जो परिवेश स्थिति को पकड़ सकते हैं। आपका उदाहरण कुछ ऐसा लिखा गया हो सकता:

    auto f = [&frequency](int x) -> void { ++frequency[x]; }; 
    

    चर है कि पहले वर्ग कोष्ठक के बीच में दिखाई देते हैं पर कब्जा कर लिया हैं। यह लैम्ब्डा निम्नलिखित स्थानीय वर्ग और वस्तु के बराबर है: कब्जा सूची में & बिना

    struct F 
    { 
        F(std::unordered_map<int, int> & m) : m_(m) { } 
        void operator()(int x) { ++m_[x]; } 
    private: 
        std::unordered_map<int, int> & m_; 
    } f; 
    

चर, मूल्य द्वारा कब्जा कर लिया जाता है, यानी एक प्रति बंद वस्तु में किया जाता है। एक शॉर्ट-हाथ के रूप में, आप या [&]को क्रमशः पर मूल्य या संदर्भ द्वारा कैप्चर करने के लिए कह सकते हैं।