2009-03-19 11 views
10

मैंने अभी सी ++ मानक में पढ़ा है कि std::for_each एक गैर-संशोधित अनुक्रम ऑपरेशन है, find, search और इसी तरह के साथ। क्या इसका मतलब यह है कि प्रत्येक तत्व पर लागू फ़ंक्शन को संशोधित नहीं करना चाहिए? ऐसा क्यों है? क्या गलत होने की सम्भावना है?std :: for_each एक गैर-संशोधित अनुक्रम ऑपरेशन क्यों है?

यहां एक नमूना कोड है, जहां अनुक्रम संशोधित किया गया है। क्या आप इसके साथ कुछ गलत देख सकते हैं?

void foo(int & i) 
{ 
    i = 12; 
} 

int main() 
{ 
    std::vector<int> v; 
    v.push_back(0); 

    std::for_each(v.begin(), v.end(), foo); 
    // v now contains 12 
} 

मुझे संदेह है कि यह सिर्फ एक व्याख्या मुद्दा है, लेकिन मैं इसके बारे में आपकी राय रखना चाहता था।

पुनश्च: मुझे लगता है मैं for_each के बजाय std::transform इस्तेमाल कर सकते हैं पता है, लेकिन उस समय नहीं है।

उत्तर

16

देखें this defect report वे कहते हैं

LWG का मानना ​​है कि मानक में कुछ भी नहीं समारोह वस्तुओं है कि अनुक्रम तत्वों को संशोधित करने पर प्रतिबंध लगाता है। समस्या यह है कि for_each "nonmutating एल्गोरिदम" नामक एक सेशन में है, और शीर्षक भ्रमित हो सकता है। एक अपरिवर्तनीय नोट को स्पष्ट करना चाहिए।

लेकिन this one पर भी ध्यान दें।

वे इसे कॉल करने के लिए "गैर बदलाव" क्योंकि for_each ही exlicitly अनुक्रम के तत्वों संशोधित नहीं करता है लगता है।

+0

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

+0

हाँ मुझे भी लगता है। यह अभी तक n2800 में नहीं है। चलो देखते हैं कि अगले मसौदे में क्या है। के रूप में टिप्पणी CD1 का दर्जा प्राप्त है, यह काफी अजीब इसे अब और में नहीं है :) मैं वे इसे हटा दिया है क्योंकि वे इसके लिए एक अवधारणा बाहर काम करना चाहता हूँ पर शक। –

+0

अच्छा लगता है! विशेष टिप्पणी में यह दोष रिपोर्ट में: "Stepanov और ली द्वारा मूल एसटीएल दस्तावेज़ खुले समारोह वस्तु अपने तर्क को संशोधित करने से मना कर"। मुझे लगता है कि के बारे में पता नहीं था। –

20

काफी सरलता से, आप एक ऐसा बदलाव नहीं कर सकते जो कंटेनर की संरचना को संशोधित कर सके। ऐसा इसलिए है क्योंकि सामान्य मामले में, एक कंटेनर को संशोधित करने वाले इटरेटर्स को अमान्य कर सकते हैं।

जब तक यह कंटेनर की संरचना (जैसे कंटेनर में तत्वों का क्रम) नहीं बदलता तब तक आप तत्व को संशोधित कर सकते हैं।

[अलावा]


नोट वहाँ कुछ भ्रम की स्थिति के बारे में for_each एक 'गैर संशोधित' एल्गोरिथ्म जा रहा प्रतीत हो रहा है कि। "सी ++ प्रोग्रामिंग भाषा, तीसरी एड" की चौथी प्रिंटिंग के लिए इरेटा में स्ट्रॉस्ट्रप द्वारा इस भ्रमित स्थिति का सारांश यहां दिया गया है। (सीपीएल) इस बारे में for_each एक दृश्य के तत्वों को संशोधित कर सकते हैं कि क्या कहना चाहता है (http://www.research.att.com/~bs/3rd_printing5.html):

"for_each() एल्गोरिथ्म nonmodifying रूप में वर्गीकृत किया जाता है क्योंकि यह स्पष्ट रूप से एक दृश्य संशोधित नहीं करता है हालांकि, अगर। एक गैर-कॉन्स अनुक्रम पर लागू for_each() अनुक्रम के तत्वों को बदल सकता है। उदाहरण के लिए, 11.9 में negate() का उपयोग देखें। " (हाल के मानक संकल्प)।

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

यह भी देखें:

6

मुझे लगता है कि "क्रम के संचालन गैर संशोधित" का मतलब है कि इस आपरेशन संशोधित नहीं अनुक्रम। लेकिन आपरेशन कंटेनर तत्वों को संशोधित कर सकता है। अलग अलग बातें -

कंटेनर तत्वों और अनुक्रम का मूल्य।

2

litb जैसा कि ऊपर संकेत दिया, for_each एसटीडी है एक 'nonmutating एल्गोरिथ्म'

एसटीएल की 'परिवर्तनशील' कि करने के लिए समकक्ष के रूप में वर्गीकृत किया जाता है :: बदलना।

चूंकि आपने संकेत दिया है कि आप जानते हैं कि आप std :: transform का उपयोग कर सकते हैं, उपरोक्त वास्तव में बिंदु बन गया है। यह आपके कोड को पढ़ने वाले लोगों को संचार के बिंदु के रूप में कार्य करता है।

अगर मैं std :: for_each देखते हैं, यह स्पष्ट है कि जो कुछ भी foo करता है, यह कंटेनर बदलाव नहीं करेगी।

दिशानिर्देश मैं पालन कहा जा सकता है:

"आप कुछ काम है कि तत्वों में परिवर्तन नहीं होता है, का उपयोग std :: for_each करने के लिए एक कंटेनर के तत्वों का उपयोग करना चाहते हैं तो

आप हैं। कुछ व्यवस्थित तरीकों से तत्वों को संशोधित करने के लिए किसी कंटेनर के तत्वों का उपयोग करना चाहते हैं या उन्हें किसी कार्य में उपयोग करना चाहते हैं जो उन्हें किसी प्रकार से बदल देगा, std :: transform का उपयोग करें। "

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