2011-11-03 9 views
5

मेरे पास कुछ कोड है जो लैम्ब्स का उपयोग करके जटिलता में बहुत कम हो सकता है। हालांकि दुर्भाग्य से हमें एक कंपाइलर का उपयोग करना है जो सी ++ 11 का पूरी तरह से समर्थन नहीं करता है और हम आसानी से स्विच नहीं कर सकते हैं। अब सवाल यह है कि लॉजिक को जितना संभव हो उतना बंद रखने के लिए लॉम्बडा-अभिव्यक्ति को उपलब्ध नहीं है (यानी std::function उपलब्ध है, लैम्बडा नहीं हैं)। हालांकि मैं यह एक बहुत नापसंद करते हैं,प्री-लैम्ब्डा कंपाइलर में लैम्ब्डा को कैसे संभालें

struct functor{ 
    functor(type & member) : m_member(member) {} 
    void operator()(...) {...} 
    type & m_member; 
}; 

void function() { 
    use_functor(functor(...)); 
} 

मैं बहुत ज्यादा इस पैटर्न के लिए इस्तेमाल किया कर रहा हूँ:

सामान्य समाधान कहीं और functor को परिभाषित करने और फिर उचित जगह पर इसका इस्तेमाल किया जा सके। कक्षा को परिभाषित करने का मुख्य कारण आम तौर पर है कि मैं एक एसटीएल के भीतर मज़ेदार का उपयोग किया जाएगा और टेम्पलेट्स को फ़ंक्शन की इनलाइन परिभाषित structs पसंद नहीं है। हालांकि मेरे मामले में use_functor() फ़ंक्शन एक सामान्य विधि होगी, इसलिए मैं फ़ंक्शन के अंदर फ़ैक्टर को परिभाषित कर सकता हूं (प्रत्येक मज़ेदार केवल एक फ़ंक्शन के भीतर उपयोग किया जाता है)।

void function() { 
    struct functor{ 
     functor(type & member) : m_member(member) {} 
     void operator()(...) {...} 
     type & m_member; 
    }; 
    use_functor(functor(...)); 
} 

यह कुछ हद तक सुधार हुआ है, लेकिन अभी भी मुझे बहुत अधिक बदसूरत कोड चाहिए जो मैं चाहूंगा। उदाहरण के लिए मैं पूरी तरह से मज़ेदार के नाम से छुटकारा पाना चाहता हूं। मुझे पता है कि एक अज्ञात संरचना बनाना संभव है, अगर मैं केवल एक मान का उपयोग करता हूं।

void function() { 
    struct{ 
     // functor(type member) : m_member(member) {} 
     void operator()(...) {...} 
     // type & m_member; 
    } callback ; 
    use_functor(callback); 
} 

हालांकि इस बिंदु पर मुझे आवश्यक डेटा सदस्यों को प्रदान करने के बारे में कोई जानकारी नहीं है। चूंकि संरचना अज्ञात है क्योंकि इसमें कोई कन्स्ट्रक्टर नहीं है। मैं आसानी से सदस्य को सेट कर सकता था, क्योंकि यह सार्वजनिक है, लेकिन फिर यह एक रेखा जोड़ देगा जो मुझे नापसंद करता है।

लक्ष्य यह है कि इसे एक राज्य में छोड़ दें, एक बार जब हम एक ऐसे कंपाइलर पर स्विच करते हैं जिसे साफ लैम्बडास पर स्विच किया जाता है जो इस समस्या को पूरी तरह से खत्म करने की अनुमति देता है।

आप यह करने के बारे में कैसे जाएंगे?

+0

जैसा कि मुझे अभी पता लगाना पड़ा था, कुछ पुराने जीसीसी फ़ंक्शन में घोंसला वाले स्ट्रक्चर से std :: function <> बहुत अच्छी तरह से रूपांतरणों को भी संभाल नहीं पाते हैं, और किसी भी समाधान को पसंद नहीं करेंगे। तो मुझे विकल्प एक का उपयोग करने और तर्क को अलग करने के लिए मजबूर किया गया है। – LiKao

उत्तर

1

के साथ एक अनाम struct के सदस्य चर के initalisation के संबंध एक निर्माता के बिना आप कर सकते हैं:

void function() { 
    type the_thing; 
    struct { 
     void operator()(...) {...} 
     type & m_member; 
    } callback = {the_thing}; 
    use_functor(callback); 
} 

callback में type & संदर्भ m_member स्थापित करने के लिए।

0

awoodland द्वारा जवाब पर विस्तार:

#define MY_LAMBDA(name, memberType, memberValue, body) \ 
    struct {          \ 
     void operator()(...) body    \ 
     memberType & memberValue;     \ 
    } name = {memberValue} 

void function() { 
    type thing_to_capture; 

    MY_LAMBDA(callback, type, thing_to_capture 
    { 
     std::cout << thing_to_capture << std::endl; 
    }); 

    use_functor(callback); 
} 

आप MY_LAMBDA उपयोग कर सकते हैं कहीं भी आप एक struct परिभाषित कर सकते हैं। दुर्भाग्य से, variadic मैक्रो के बिना, आप एक ही वस्तु में सब पर कब्जा कर लिया वस्तुओं रैप करने के लिए है, और आप "लैम्ब्डा घोषणा"

भी ध्यान रखें कि एक लैम्ब्डा का उपयोग कर बराबर होगा में उस वस्तु के प्रकार के बारे में बताने की:

void function() { 
    type thing_to_capture; 

    auto callback = [&thing_to_capture]() 
    { 
     std::cout << thing_to_capture << std::endl; 
    }; 

    use_functor(callback); 
} 
+0

टाइपो के मौके को खत्म करने के लिए, आप मैक्रो के शीर्ष पर 'type thing_to_capture;' जोड़ सकते हैं (यदि आप इस उदाहरण में एक स्पष्ट c'tor और कॉपी-असाइनिंग नहीं कर रहे हैं)। – Richard

+1

'MY_LAMBDA'' ऑपरेटर() 'की परिभाषा निर्दिष्ट करने की क्षमता के बिना कैसे उपयोगी है? – ildjarn

+0

@ildjarn अच्छा बिंदु ... आगामी संपादित करें। –

0

आप लैम्ब्डा लाइब्रेरी या boost::phoenix को बढ़ावा देने का प्रयास कर सकते हैं। वे दोनों वास्तविक लैम्ब्डा समर्थन के बिना लैम्ब्डा स्टाइल ऑपरेशंस करने के लिए डिज़ाइन किए गए हैं। चूंकि वे टेम्पलेट आधारित हैं, इसलिए जब कुछ उम्मीद के अनुसार काम नहीं करता है तो त्रुटियों को डीबग करना मुश्किल हो सकता है।

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