2010-01-20 12 views
8

http://www.cplusplus.com/reference/algorithm/for_each/
यूनरी फ़ंक्शन में तर्क के रूप में एक तत्व ले रहा है। यह या तो किसी फ़ंक्शन या ऑब्जेक्ट का पॉइंटर हो सकता है जिसका वर्ग ऑपरेटर() को अधिभारित करता है। इसका वापसी मूल्य, यदि कोई है, अनदेखा किया जाता है।क्यों फॉर_एच अपने मज़ेदार तर्क को संशोधित नहीं कर सकता?

इस लेख के अनुसार, मैं उम्मीद है कि for_each वास्तव में वस्तु अपने तीसरे तर्क के रूप में दिए गए संशोधित करता है, लेकिन ऐसा लगता है for_each की तरह एक अस्थायी वस्तु पर चल रही है, और यहां तक ​​कि वस्तु यह करने के लिए दिया संशोधित नहीं करता है।

तो, इस तरह से इसे क्यों लागू किया जाता है? यह बहुत कम उपयोगी लगता है। या मैंने कुछ गलत समझा और नीचे दिए गए मेरे कोड में त्रुटियां हैं?

#include <iostream> 
#include <vector> 
#include <algorithm> 

template <class T> struct Multiplicator{ 
    T mresult; 
    public: 
    const T& result() const{return mresult;} 
    Multiplicator(T init_result = 1){ 
     mresult = init_result; 
    } 
    void operator()(T element){ 
     mresult *= element; 
     std::cout << element << " "; // debug print 
    } 
}; 

int main() 
{ 
    std::vector<double> vec; 
    vec.push_back(1); 
    vec.push_back(2); 
    vec.push_back(3); 
    Multiplicator<double> multiply; 
    std::for_each(vec.begin(),vec.end(),multiply); 
    std::cout << "\nResult: " << multiply.result() << std::endl; 
    return 0; 
} 

अपेक्षित उत्पादन:

1 2 3 Result: 6 

लेकिन उत्पादन निम्नलिखित गया:

1 2 3 Result: 1 
+0

अपना प्रश्न शीर्षक बदलने के बारे में कैसे? दूसरों को ढूंढना आसान हो सकता है। – BeeBand

उत्तर

15

समारोह वस्तु मूल्य द्वारा लिया जाता है। for_each समारोह वस्तु देता है, इसलिए यदि आप इसे करने के लिए बदलने के लिए:

multiply = std::for_each(vec.begin(),vec.end(),multiply); 

आप उम्मीद उत्पादन मिलता है।

+1

आम तौर पर मज़दूरों के लिए, और क्योंकि उन्हें हल्के और प्रतिलिपि बनाने योग्य माना जाता है, मैं धोखा देती हूं और एक विशेषता का उपयोग करता हूं जो कि कन्स्ट्रक्टर में पारित एक चर का संदर्भ देता है। इस प्रकार कोई भी प्रतिलिपि काफी समकक्ष है और उसी आइटम को संदर्भित करती है। बेशक, यह प्रारंभिकता को थोड़ा अजीब बनाता है (परिवर्तनीय घोषित करता है, इसे मज़ेदार से पास करता है, परिवर्तनीय से पढ़ता है), लेकिन यह ठीक काम करता है और किसी भी विशेष कार्यान्वयन स्वामित्व की आवश्यकता नहीं होती है (जैसे कि संशोधित मज़ेदार को छोड़ना नहीं)। –

+0

लेमे आपको पहला स्वर्ण एसटीएल बैज –

+0

@ जोहान्स देता है: धन्यवाद, लेकिन मुझे टैग किए गए 36 प्रश्नों का उत्तर देना होगा [stl] पहले :-) (आवश्यकता अब कम से कम 1,000 अपवॉट्स और कम से कम 200 उत्तरों हैं; मुझे याद है जब उन्होंने इसे एक साल पहले बदल दिया और मैंने कुछ महीनों के लिए अपना स्वर्ण [सी] बैज खो दिया।) –

10

जबकि जेम्स सही है, std::multiplies साथ std::accumulate का उपयोग कर अधिक सही होगा, शायद:

#include <iostream> 
#include <functional> 
#include <numeric> 
#include <vector> 

int main(void) 
{ 
    std::vector<double> vec; 
    vec.push_back(1); 
    vec.push_back(2); 
    vec.push_back(3); 

    double result = std::accumulate(vec.begin(), vec.end(), 
            1.0, std::multiplies<double>()); 

    std::cout << "\nResult: " << result << std::endl; 

} 
अपने for_each संस्करण के साथ

, तुम सच में फिर से functor कॉपी करने के लिए, बल्कि जरूरत नहीं है:

double result = std::for_each(vec.begin(), vec.end(), multiply).result(); 

या C++ 0x, मनोरंजन के लिए:

double result = 1; 
std::for_each(vec.begin(), vec.end(), [&](double pX){ result *= pX; }); 
+0

यह क्या है, "नौकरी के दिन के लिए सही उपकरण का सुझाव है?" :-) +1 –

+0

टिप के लिए धन्यवाद। – smerlin

+0

@ जेम्स: 8) दुर्भाग्यवश, मेरे उत्तरों की गुणवत्ता तेजी से घट जाती है क्योंकि दिन जारी रहता है। : p – GManNickG

0

For_each का अर्थशास्त्र आप जो करने की कोशिश कर रहे हैं उसमें फिट नहीं है। जो भी आप कोशिश कर रहे हैं वह जमा करता है, इसके बजाए इसका उपयोग करें।

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