2009-12-24 18 views
7

मैं सी #+ में लैम्ब्डा के साथ काम करने की कोशिश कर रहा हूं ताकि उन्हें सी # में एक बड़ा सौदा किया जा सके। मेरे पास वर्तमान में एक बूस्ट टुपल है (यह वास्तव में सरलीकृत संस्करण है)।सी ++ 0x में लैम्ब्डा कैश कैसे करें?

typedef shared_ptr<Foo> (*StringFooCreator)(std::string, int, bool) 
typedef tuple<StringFooCreator> FooTuple 

मैं तो मेरे FooTuple में ग्लोबल नेम स्पेस में एक समारोह लोड। आदर्श रूप में, मैं इसे एक लैम्ब्डा से बदलना चाहता हूं।

tuplearray[i] = FooTuple([](string bar, int rc, bool eom) -> {return shared_ptr<Foo>(new Foo(bar, rc, eom));}); 

मैं यह नहीं समझ सकता कि लैम्ब्डा टुपल के लिए फ़ंक्शन हस्ताक्षर क्या होना चाहिए। यह स्पष्ट रूप से एक फ़ंक्शन पॉइंटर नहीं है, लेकिन मैं यह नहीं समझ सकता कि लैम्ब्डा का हस्ताक्षर क्या होना चाहिए। लैम्ब्डा के लिए संसाधन अभी बहुत पतले हैं। मुझे एहसास है कि इस समय सी ++ 0x प्रवाह में है, लेकिन मैं काम करने के लिए इसे कैसे प्राप्त करने के बारे में उत्सुक था। मुझे यह भी पता है कि ऐसा करने के लिए सरल तरीके हैं, लेकिन मैं बस सी ++ 0x के साथ खेल रहा हूं। मैं इंटेल 11.1 कंपाइलर का उपयोग कर रहा हूं।

उत्तर

7

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

इस कोड जीसीसी और VC10 (tr1/हटाने कुलपति के लिए भी शामिल है से) पर काम करता है:

#include <tr1/tuple> 
#include <tr1/functional> 
#include <tr1/memory> 

using namespace std; 
using namespace std::tr1; 

class Foo{}; 
typedef function<shared_ptr<Foo>(string, int, bool)> StringFooCreator; 
typedef tuple<StringFooCreator> FooTuple; 

int main() { 
    FooTuple f(
     [](string bar, int rc, bool eom) { 
      return make_shared<Foo>(); 
     } 
    ); 

    shared_ptr<Foo> pf = get<0>(f)("blah", 3, true); 
} 
+0

काम नहीं करेगा - एक लैम्ब्डा अभिव्यक्ति फ़ंक्शन पॉइंटर नहीं है। यह (अवधारणात्मक रूप से) एक अज्ञात मजेदार वर्ग है। मैंने जो चीजें पढ़ी हैं, उससे –

+0

, संकलक इसे समझने में सक्षम होना चाहिए और अगर यह नहीं कर सकता है तो मुझे बताएगा। मैं इसे देख लूंगा। धन्यवाद। – Steve

+0

@Terry hmm यह अजीब है, क्योंकि यह कोड अभी संकलित करता है और जीसीसी पर चलता है। – joshperry

1

आप एक std :: समारोह में एक लैम्ब्डा स्टोर करने के लिए सक्षम होना चाहिए। अपने उदाहरण में, एक

std::function<std::shared_ptr<Foo>(std::string,int,bool)>

में भंडारण की कोशिश ऑटो के बारे में मत भूलना (यद्यपि आप आदि ऑटो के की एक सरणी, बनाने के लिए सक्षम नहीं होगा)।

+0

क्या आप किसी भी मौके से std :: function के लिए हेडर जानते हैं? Google मेरी मदद नहीं कर रहा है ... – Steve

+0

भी, ऑटो से आपका क्या मतलब है? – Steve

+2

std :: फ़ंक्शन ऑटो एक और सी ++ 0x सुविधा –

3

Visual C++ Blog

से मैं tr1 :: कार्यों में lambdas भंडारण उल्लेख किया है। लेकिन आपको नहीं करना चाहिए, जब तक कि यह आवश्यक न हो, tr1 :: फ़ंक्शन में कुछ ओवरहेड है। यदि आप एक लैम्ब्डा का पुन: उपयोग करना चाहते हैं, या बस इसे एक नाम देना चाहते हैं, तो आप ऑटो का उपयोग कर सकते हैं।

+1

'ऑटो' यहां कोई मदद नहीं है, क्योंकि इसे 'वेक्टर' जैसे कंटेनर के लिए टाइप पैरामीटर के रूप में उपयोग नहीं किया जा सकता है। –

+0

यह सच है, मैं सिर्फ ओवरहेड का उल्लेख करना चाहता था। –

+0

इंटेल कंपाइलर पर, फ़ंक्शन के साथ लैम्ब्डा फ़ंक्शन पॉइंटर को कैशिंग करने से अभी भी तेज़ है। मेरे परीक्षणों से लगभग 3-5% तेज। पारितोषिक के लिए धन्यवाद। – Steve

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