2016-09-13 13 views
5

मेरे पास निम्न कोड है। क्या आप मुझे समझा सकते हैं कि यह कैसे काम करता है?सी ++ 11: लैम्ब्डा, करी

template<typename Function, typename... Arguments> 
auto curry(Function func, Arguments... args) { 
    return [=](auto... rest) { 
     return func(args..., rest...); 
    }; 
} 

int main() { 
    auto add = [](auto x, auto y) { 
     return x + y; 
    }; 
    auto add4 = curry(add, 4); 
    std::cout << add4(3) << '\n'; //output: 7. (Ok) 

} 
+1

क्या आपके पास कोई समझ नहीं है जिसे आप समझ में नहीं आ रहे हैं? – Hayt

उत्तर

10

सबसे पहले, आप को पता है कि currying है है, या अपने प्रश्न में, यह विशेष रूप से partial application का मामला (जो करने के लिए currying संबंधित है, लेकिन थोड़ा अलग) है।

असल में, यह मानकों की एक निश्चित संख्या के साथ कम करने एक समारोह एक और समारोह तय पैरामीटर के मूल्यों से कुछ के साथ बनाने के लिए मायने रखता है।

मैं अपने exampled, मूल कार्य add(x,y) जो दो पैरामीटर एक्स और y है। आप को कम समारोह के arity एक्स की स्थापना से 4 से जोड़ सकते हैं और कम समारोह add4(y) ऐसे

रूप add4 (y) बनाने = जोड़ने (एक्स, वाई) जहां एक्स = 4

अब यह आपके सी ++ कोड में कैसे प्राप्त किया जाता है? विविधता टेम्पलेट्स, विविधता फ़ंक्शन और लैम्ब्डा फ़ंक्शंस की सहायता से।

Lambda functions सी ++ 11 के बाद से सी ++ में हैं। संक्षेप में वे फ्लाई पर बनाए गए अज्ञात फ़ंक्शन हैं, जिन्हें एक चर में संग्रहीत किया जा सकता है। आप main() में एक लैम्ब्डा के रूप में add बनाएँ:

auto add = [](auto x, auto y) { 
return x + y; 
}; 

एक पैटर्न से लैम्ब्डा पहचानता [] (list-of-arguments) {function-body};

नोट: [] हमेशा खाली नहीं है, there "चर पर कब्जा" देखते हैं, हम वापस करने के लिए मिल जाएगा बाद में।

अब करी समारोह का उद्देश्य func की पहली बहस के लिए इन lambdas कार्यों func और तर्क के रूप में मूल्यों की एक निश्चित संख्या में से एक लेने के लिए, और मान निर्दिष्ट द्वारा एक नए कार्य परिभाषित करते हैं, यह है, ।

"तर्कों की निश्चित संख्या" तंत्र (जब तक वे संकलन समय के रूप में जाना जाता है) variadic template तर्क Arguments... args जो टेम्पलेट पैरामीटर के रूप में प्रकार के किसी भी संख्या के साथ टेम्पलेट कॉल करने के लिए अनुमति देता है द्वारा अनुमति दी है। तो हमारे मामले में, पारित तर्क 4 है, इसलिए Arguments... args को int द्वारा प्रतिस्थापित किया जाएगा, और curry का उदाहरण लैम्ब्डा और int पैरामीटर के रूप में स्वीकार करेगा।

अगर हम curry के कोड को देखो, हम देखते हैं कि यह केवल एक लैम्ब्डा समारोह ही है, (यह एक variadic function है, बस printf() की तरह) जिसका एकमात्र उद्देश्य है तर्क जिसका मूल्य पहले से ही तय हो गई है जब instantiating श्रेणीबद्ध करने के लिए है टेम्पलेट (args...) और जिनके मूल्य को करीबी फ़ंक्शन (rest...) पर तर्क के रूप में पारित किया गया है।

[=] पर हस्ताक्षर लैम्ब्डा समारोह के लिए विशेष कब्जा समारोह जो शरीर में सभी स्थानीय चर उपयोग करने के लिए अनुमति देता है (यहां यह args का उपयोग कर सकेगा)।

तो यह रैप करने के लिए ऊपर, यहाँ क्या आपका मुख्य समारोह में क्या हो रहा है:

  1. आप add नामक एक चर जो एक लैम्ब्डा समारोह, दो तर्क लेने और उन्हें जोड़ने शामिल पैदा करते हैं।
  2. जब आप curry(add,4) पर कॉल करते हैं तो आप curry टेम्पलेट को तुरंत चालू करते हैं। 4 के प्रकार, यानी int
  3. :
    • पहले टेम्पलेट पैरामीटर Functionadd के प्रकार (एक लैम्ब्डा दो int ले रहे हैं और एक int लौटने)
    • दूसरा variadic मापदंडों केवल एक ही प्रकार होता है

तत्काल curry फ़ंक्शन इस

जैसा दिखता है
curry((int,int)->(int) func, int arg){ 
    return [=](auto... rest) {return func(arg, rest...);}; 
} 

ध्यान दें कि auto और टेम्पलेट प्रकार की कटौती के कारण आप इन प्रकारों को कभी नहीं देखते हैं।

  1. फिर आप func = add और arg = 4

  2. आप add4 में इस इन्स्टेन्शियशन जो अब एक लैम्ब्डा एक पैरामीटर ले रहा है का परिणाम की दुकान के साथ इस उदाहरण कहते हैं। इसके बाद आप तर्क के रूप में 3 के साथ add4 कॉल कर सकते हैं (rest... 3) है, जो तब add(4,3) फोन और वापसी 7.

ध्यान दें कि तकनीकी रूप से आप एक से अधिक तर्क के साथ add4 कॉल करने के लिए कोशिश कर सकते, curried समारोह के बाद से होगा एक विविध कार्य है। संकलक केवल तभी विफल होगा जब यह पता चलता है कि add पर कॉल करते समय इन अतिरिक्त तर्कों के लिए कोई स्थान नहीं है (इसे here देखें)

+0

ग्रेट धन्यवाद! अब पढ़ना! आपने बहुत कुछ लिखा है :) – Cfon

+5

ध्यान दें कि ओपी का कोड करी नहीं है, बल्कि आंशिक अनुप्रयोग है। बहुत से लोग दोनों के बीच उलझन में हैं। करी का अर्थ एन तर्कों का एक कार्य लेने और इसे 1 तर्क के एन कार्यों की श्रृंखला में बदलना है। – Yakk

+0

हाँ, आप सही हैं। मेरे मामले में, यह आंशिक आवेदन। – Cfon

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