2011-11-14 27 views
7

पुनरावृत्ति एक वेक्टर से अधिक काम करता है: सेटstd :: std :: सेट पर for_each, सी ++ 11

std::vector<int> collection = {2, 3, 4, 5435345, 2}; 
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;}); 

लेकिन एक से अधिक नहीं (त्रुटि संकलन):

std::set<int> collection = {2, 3, 4, 5435345, 2}; 
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;}); 

क्यों ' मैं std::for_each के साथ std::set पर पुन: प्रयास करता हूं?

बोनस सवाल: इसके अलावा, मैं auto& को लैम्ब्डा के तर्क में int& परिवर्तन करना चाहते हैं, क्यों इस स्वचालित रूप से निष्कर्ष निकाला जा सकता है?

उत्तर

19

std::set<T>::value_typeT const है, T नहीं; नतीजतन, आपके लैम्ब्डा का तर्क एक मान प्रकार (यानी, प्रतिलिपि) या int const& (और तकनीकी रूप से, या int const volatile&) होना चाहिए, int& नहीं होना चाहिए। अर्थात, और यह काम करता है:

std::set<int> collection{2, 3, 4, 5435345, 2}; 
std::for_each(
    collection.begin(), 
    collection.end(), 
    [](int const& i) { std::cout << i << std::endl; } 
); 

बोनस सवाल: इसके अलावा, मैं auto& को लैम्ब्डा के तर्क में int& परिवर्तन करना चाहते हैं, क्यों इस स्वचालित रूप से निष्कर्ष निकाला जा सकता है?

क्योंकि मानक कहता है कि यह नहीं कर सकता; ऐतिहासिक रूप से, मेरा मानना ​​है कि यह भेड़-बकरियों और अवधारणाओं के बीच अत्यधिक जटिल बातचीत के कारण था (ड्राफ्ट से अवधारणाओं को हटा दिए जाने से पहले)। हालांकि, मुझे अफवाहें सुनाई देती हैं कि नए (सी ++ 11) मानक की पहली दोष रिपोर्ट ठीक से संबोधित करेगी, इसलिए यह संभव है कि आप अगले वर्ष या दो में अपनी पसंद के कंपाइलर में जोड़े गए समर्थन के लिए समर्थन देखेंगे। EDIT: ओह, देखो, सी ++ 14 में अब पॉलिमॉर्फिक लैम्बडास है ...

+0

आपने यह कहां सुना? हर्ब सटर के ब्लॉग पर उन्होंने उल्लेख किया कि वे पॉलीमोर्फिक लैम्ब्डा को तब तक नहीं जोड़ेंगे जब तक अवधारणाओं की समस्या का समाधान नहीं हो जाता है, क्योंकि वे अभी भी भविष्य में अवधारणाओं की तरह एक विशेषता चाहते हैं। –

+0

लॉल क्या राजनेता है। :) तो जवाब से बाहर ले लो, क्या आप? – wilhelmtell

0

आपको एक सेट पर फिर से भरने में सक्षम होना चाहिए। हालांकि, ध्यान दें कि चूंकि एक सेट में तत्व भी इसकी कुंजी है, इसे संशोधित नहीं किया जा सकता है। const संदर्भ लेने के लिए अपना कोड बदलें, और इसके बजाय cbegin/cend का उपयोग करें, भले ही कोई सेट है या नहीं, जब आप तत्वों को संशोधित नहीं कर रहे हैं।

1

एक अस्वीकृत set<int> इटरेटर const int& है। तो आप इसे const के बिना int& पैरामीटर के रूप में पास नहीं कर सकते हैं। या तो सादा (int i) या (const int& i) आज़माएं।

और यह वास्तव में उन स्थानों में से एक नहीं है जिन्हें आपको auto का उपयोग करने की अनुमति है। मुझे लगता है कि auto केवल प्रारंभिक या घोषणा के पीछे प्लेसहोल्डर के रूप में एक घोषणा में काम करता है।

3

बोनस प्रश्न के बारे में: एक "ऑटो" फ़ंक्शन तर्क लैम्बडास के लिए विशिष्ट नहीं है। आप यह भी पूछ सकते हैं कि हम सभी फ़ंक्शंस को f(auto x, auto y) के रूप में घोषित करने की अनुमति क्यों नहीं देते हैं। लेकिन इसका मतलब यह है कि आप अनिवार्य रूप से फ़ंक्शन टेम्पलेट्स द्वारा सभी कार्यों को प्रतिस्थापित करना चाहते हैं। ऐसा माना जाता था कि मौजूदा सी ++ भाषा और विशेष रूप से टाइप सिस्टम के साथ अच्छी तरह से काम नहीं करना है। यदि आप फ़ंक्शन टेम्पलेट चाहते हैं, तो पहले से ही एक मौजूदा वाक्यविन्यास और तंत्र है, और "ऑटो" तर्क घोषित करने का तरीका नहीं है।

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