2009-09-29 10 views
6

मैं हाल ही में इंटरनेट पर लैम्ब्डा अभिव्यक्तियों के बारे में कुछ पढ़ रहा हूं और ऐसा लगता है कि सी ++ 0x के लैम्ब्डा अभिव्यक्तियों में एक प्रकार (या प्रकार) नहीं होगा जो विशेष रूप से लैम्ब्डा अभिव्यक्तियों से बंधेगा - दूसरे शब्दों में , लैम्ब्डा एक्सप्रेशन केवल टेम्पलेट तर्क या auto तर्क/चर से मेल खाते हैं। क्या, here वर्णित है, ऐसा होता है किक्या यह बुरा है कि C++ 0x के लैम्ब्डा अभिव्यक्तियों का नाम नहीं है?

संकलनकर्ता कि lambdas समर्थन प्रत्येक लैम्ब्डा अभिव्यक्ति

मेरा प्रश्न है के लिए एक अनूठा गुमनाम functor प्रकार बनाएगा है, यह है कि एक बुरी बात? क्या यह कुछ ऐसा कीवर्ड नहीं समझ पाएगा जो केवल लैम्ब्डा अभिव्यक्तियों से मेल खाता हो, उदा। lambda है, जो इस प्रकार

void f(std::function<int(int)> func) 
{ 
    func(2); 
} 

template<typename T> 
void g(T func) 
{ 
    func(2); 
} 

void h(lambda func) 
{ 
    func(2); 
} 

int main() 
{ 
    int fpointer(int); 
    struct { int operator()(int var) { return var; } } functor; 

    f(fpointer); //ok (actually a linker error, but for the sake of example) 
    f(functor); //ok 
    f([](int var) { return var; }); //ok 

    g(fpointer); //ok 
    g(functor); //ok 
    g([](int var) { return var; }); //ok 

    h(fpointer); //error -- function pointer isn't a lambda expr 
    h(functor); //error -- functor isn't a lambda expr 
    h([](int var) { return var; }); //ok 

    return 0; 
} 

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

संक्षेप में, मेरा सवाल यह है कि, यह ठीक है कि लैम्ब्डा अभिव्यक्ति अज्ञात हैं (उपयोगिता के मामले में दोनों - lambda प्रकार की कमी हमें कुछ कार्यक्षमता से रहित करती है - और दार्शनिक रूप से - क्या यह वास्तव में समझ में आता है लैम्बडा अभिव्यक्तियों में हमेशा 'टाइप' auto है)?

+6

यह थोड़ा सा लगता है जैसे आप जानते हैं कि आप 'std :: function 'का उपयोग करके लैम्ब्डा अभिव्यक्ति स्वीकार कर सकते हैं। –

+0

मैं था, हालांकि सामान्य कार्यक्षमता मेल खाता है कि कैसे 'ऑटो' काम करता है (afaik), मैंने सोचा कि यह * कार्यों * फ़ंक्शन कॉल का एक और * सेट जोड़ने के लिए अनावश्यक है (लेकिन यह उल्लेख करने के लिए अभी भी अच्छा है, इसलिए धन्यवाद litb) – GRB

+2

मुझे लगता है ऑटो के बारे में एक गलतफहमी है। एक फ़ंक्शन में पैरामीटर प्रकार के रूप में ऑटो का उपयोग नहीं किया जा सकता है। यह एक प्रकार नहीं है। ऑटो बस कहता है "प्रारंभकर्ता से प्रकार को कम करें क्योंकि मैं बहुत आलसी हूं या बस नाम का नाम देने में असमर्थ हूं"। – sellibitze

उत्तर

11

लैम्ब्डा स्वतंत्र प्रकार हैं। कोड

void h(lambda func) 
{ 
    func(2); 
} 

कोई मतलब नहीं है क्योंकि lambdas क्रम बहुरूपता जरूरत नहीं है। याद रखें कि एक लैम्ब्डा

struct unique_name 
{ 
    return_type operator()(Arg1 a1, Arg2 a2, ... , Argn an) 
    { 
     code_inside_lambda; 
    } 
} 

के बराबर है जो स्वयं एक अद्वितीय प्रकार है। कोड ऊपर

void h(class C) 
{ 
    C(2); 
} 

कौन सा भी कोई मतलब नहीं है, भले ही हम विश्वास दिलाता हूं सी operator() है कि बनाता है यह कहते हुए ही होगा। आपको एक टेम्पलेट चाहिए:

template<typename T> 
void g(T func) 
{ 
    func(2); 
} 

int main() 
{ 
    g([](int x){return x + 2;}); 
} 
+0

आप 'शून्य एच (कक्षा सी)' रखने के विचार के बारे में एक अच्छा मुद्दा बनाते हैं, हालांकि मैं * * v 'void h (functor_name c) कर सकते हैं जो केवल उस विशेष फ़ैक्टर प्रकार के पैरामीटर से मेल खाएगा। मैं लैम्ब्डा अभिव्यक्ति के साथ ऐसा नहीं कर सकता। – GRB

+1

यदि आपको नाम से किसी विशेष लैम्ब्डा को संदर्भित करने की आवश्यकता है, तो आपको इसे 'struct' का उपयोग करके पुराने तरीके से परिभाषित करना चाहिए। एक लैम्ब्डा अभिव्यक्ति, परिभाषा के अनुसार, अज्ञात है। – rlbond

+0

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

3

मुझे फ़ंक्शन का नाम अलग करने के आधार पर फ़ंक्शन प्रकारों को अलग करने का कोई कारण नहीं दिखता है। लैम्ब्डा फ़ंक्शंस केवल एक शॉर्टेंड हैं, जिससे आप सुविधा सुविधा को आसानी से परिभाषित कर सकते हैं। नाम या कोई नाम नहीं, फ़ंक्शन का व्यवहार वही होता है।

इस तरह से सोचें। आपके सॉफ़्टवेयर के प्रारंभिक संस्करण में एक अज्ञात फ़ंक्शन के रूप में परिभाषित एक अनुमान है। समय के साथ, आवश्यकताओं को और अधिक जटिल हो जाता है, और आपकी भविष्यवाणी भी अधिक जटिल हो जाती है - और शायद आपको इसे एक से अधिक स्थानों से कॉल करने की आवश्यकता है। करने के लिए समझदार बात यह है कि आपके पास नामित फ़ंक्शन है।

कोई कारण नहीं है कि बुलाया गया फ़ंक्शन (जिसे भविष्यवाणी करने वाला व्यक्ति) उस पर ध्यान देना चाहिए। सरल या जटिल, नाम या अनाम - यह अभी भी एक अनुमानित कार्य है।

एक मामूली समस्या बंद होने की है - मैंने जांच नहीं की है, लेकिन थोड़ी सी किस्मत के साथ, सी ++ को बंदरगाहों के साथ-साथ लैम्ब्स के साथ नामित कार्यों को घोंसला मिलेगा।

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