2016-07-27 7 views
20

मैं निम्नलिखित चर एक लैम्ब्डा युक्त है कहो। क्या मैं इस के साथ कुछ कर सकता हूं?सी ++ 11 'ऑटो' लैम्ब्डा को एक अलग Lambda में बदलें?</p> <pre><code>auto a = [] { return true; }; </code></pre> <p>और मैं <code>a</code> चाहते बाद में <code>false</code> वापस जाने के लिए:

binary '=' : no operator found which takes a right-hand operand of type 
'main::<lambda_a7185966f92d197a64e4878ceff8af4a>' (or there is no acceptable conversion) 

IntelliSense: no operator "=" matches these operands 
     operand types are: lambda []bool()->bool = lambda []bool()->bool 

वहाँ किसी भी तरह से कुछ इस तरह प्राप्त करने के लिए है:

a = [] { return false; }; 

इस वाक्य रचना मुझे निम्न त्रुटियों देता है? मैं auto वैरिएबल को एक अलग लैम्ब्डा में बदलना चाहता हूं। मैं एक शुरुआत करने वाला हूं, इसलिए मुझे auto या लैम्बडास के बारे में कुछ जानकारी याद आ रही है। धन्यवाद।

+2

'bool b = true है; ऑटो ए = [और बी] {वापसी बी; }; बी = झूठा; 'समाधान लेकिन यह निश्चित रूप से सभी परिस्थितियों में सामान्यीकृत नहीं है। – MSalters

उत्तर

31

प्रत्येक लैम्ब्डा अभिव्यक्ति एक नया अनूठा प्रकार बनाती है, इसलिए आपके पहले लैम्ब्डा का प्रकार आपके दूसरे (example) के प्रकार से अलग है। इसके अतिरिक्त एक लैम्ब्डा के कॉपी-असाइनमेंट ऑपरेटर को हटाए गए (example) के रूप में परिभाषित किया गया है, इसलिए आप इसे करने में दोगुना-अक्षम हैं। ऐसा ही प्रभाव के लिए, आप a एक std::function वस्तु हो, हालांकि यह आप कुछ प्रदर्शन

खर्च करेंगे हो सकता है
std::function<bool()> a = [] { return true; }; 
a = [] { return false; }; 
32

एक लैम्ब्डा तो जैसे एकल + ऑपरेटर का उपयोग एक समारोह सूचक लिए परिवर्तित किया जा सकता है:

+[]{return true;} 

जब तक कैप्चर समूह खाली होता है और इसमें auto तर्क नहीं होते हैं।

यदि आप ऐसा करते हैं, तो आप एक ही चर के लिए अलग-अलग लैम्बडा असाइन कर सकते हैं जब तक कि लैम्ब्डा के सभी समान हस्ताक्षर हों।

आपके मामले में,

Live example on Coliru

संकलन होगा दोनों और अधिनियम के रूप में आप की उम्मीद है। आप फ़ंक्शन पॉइंटर्स का उपयोग उसी तरह कर सकते हैं जैसे आप लैम्ब्डा का उपयोग करने की अपेक्षा करेंगे, क्योंकि दोनों functors के रूप में कार्य करेंगे।


1. सी ++ 14 में, आप lambdas auto तर्क प्रकार के रूप में के साथ, घोषणा कर सकते हैं [](auto t){} की तरह। ये generic lambdas हैं, और एक टेम्पलेट operator() है। चूंकि फ़ंक्शन पॉइंटर टेम्पलेट फ़ंक्शन का प्रतिनिधित्व नहीं कर सकता है, इसलिए + चाल सामान्य लैम्ब्स के साथ काम नहीं करेगी।

2. तकनीकी रूप से, आपको असाइनमेंट पर दूसरे + ऑपरेटर की आवश्यकता नहीं है। लैम्ब्डा असाइनमेंट पर फ़ंक्शन पॉइंटर प्रकार में परिवर्तित हो जाएगा। हालांकि, मैं स्थिरता पसंद है।

+10

वह क्षण जब सी ++ आधिकारिक तौर पर पर्ल क्षेत्र में प्रवेश कर चुका है! – peppe

+0

@jaggedSpire मुझे इस बार इतनी बुरी जरूरत है, और मैंने सोचा कि एकमात्र समाधान इस प्रश्न के अन्य 'फ़ंक्शन' जवाब था। आप इसके बारे में कैसे पता लगाया? मैंने इसे पहले कभी नहीं देखा है। –

+0

@ जोनाथन मैं वास्तव में साइडबार में एक संबंधित लिंक का पालन करने के बाद इसे एक बार मिला: [एक सकारात्मक लैम्ब्डा: '+ [] {}' - यह क्या जादू है?] (Http://stackoverflow.com/questions/18889028) – jaggedSpire

4

प्रत्येक लैम्ब्डा का एक अलग प्रकार होता है ताकि आप इसे बदल सकें। आप एक मनमानी कॉल करने योग्य ऑब्जेक्ट को पकड़ने के लिए std::function का उपयोग कर सकते हैं, जिसे इच्छानुसार बदला जा सकता है।

template<typename T> 
struct memfun_type 
{ 
    using type = void; 
}; 

template<typename Ret, typename Class, typename... Args> 
struct memfun_type<Ret(Class::*)(Args...) const> 
{ 
    using type = std::function<Ret(Args...)>; 
}; 

template<typename F> 
typename memfun_type<decltype(&F::operator())>::type 
FFL(F const &func) 
{ // Function from lambda ! 
    return func; 
} 

उसके बाद हम क्या करने में सक्षम हो जाएगा (के बाद से 'एक' std :: समारोह प्रकार अब है):

std::function <bool()> a = [] { return true; }; 
a = [] { return false; }; 
+0

मुझे लगता है कि रयान ने आपको वही चीज़ पोस्ट करने में हराया था। लेकिन आप अर्धविराम गायब हैं। –

1

हम :: समारोह एसटीडी retrospective call का उपयोग लैम्ब्डा कन्वर्ट करने के लिए कर सकते हैं

auto a = FFL([] { return false; }); 
a = FFL([] { return true; }); 
+0

थोड़ा और स्पष्टीकरण अच्छा रहा होगा। –

0

C++17 जब से तुम std::function टेम्पलेट पैरामीटर Class template argument deduction को निष्कर्ष निकाला धन्यवाद हो सकता है। यह भी कब्जा lambdas के साथ काम करता है:

int a = 24; 

std::function f = [&a] (int p) { return p + a; }; 
f    = [&a] (int p) { return p - a; }; 
f    = [] (int p) { return p; }; 

यह और अधिक जटिल हस्ताक्षर और deduced वापसी प्रकार के साथ और भी अधिक के साथ काम में आता।

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