2010-05-29 11 views
15

कल मैं इस बारे में सोच रहा था कि विंडोज एपीआई कार्यों के लिए कॉलबैक लिखने के लिए सी ++ 0x लैम्ब्डा फ़ंक्शंस की सुविधा का उपयोग करना संभव होगा या नहीं।क्या सी ++ 0x समर्थन __stdcall या बाहरी "सी" कैप्चर-कुछ भी नहीं है lambdas?

उदाहरण के लिए, अगर मैं EnumChildProc के रूप में EnumChildWindows के साथ लैम्ब्डा का उपयोग करना चाहता हूं तो क्या होगा? कुछ की तरह:

EnumChildWindows(hTrayWnd, CALLBACK [](HWND hWnd, LPARAM lParam) { 
     // ... 
     return static_cast<BOOL>(TRUE); // continue enumerating 
    }, reinterpret_cast<LPARAM>(&myData)); 

एक अन्य प्रयोग किया जाएगा सी दिनचर्या के लिए extern "C" कॉलबैक लिखने के लिए। उदा .:

my_class *pRes = static_cast<my_class*>(bsearch(&key, myClassObjectsArr, myClassObjectsArr_size, sizeof(my_class), extern "C" [](const void *pV1, const void *pV2) { 
     const my_class& o1 = *static_cast<const my_class*>(pV1); 
     const my_class& o2 = *static_cast<const my_class*>(pV2); 

     int res; 
     // ... 
     return res; 
    })); 

क्या यह संभव है?

मैं समझ सकता हूं कि चरम पर कब्जा करने वाले लैम्ब्स कभी भी सी के साथ संगत नहीं होंगे, लेकिन कम से कम मुझे लगता है कि कैप्चर-कुछ नहीं लैम्बडा संगत हो सकता है।

+0

यह सी ++ 11 मानक के खिलाफ एक दोष रिपोर्ट में स्पष्ट किया गया था, जैसा कि मैंने नीचे दिए गए मेरे उत्तर में बताया है। –

उत्तर

14

काम करने के लिए सूचक के लिए are implicitly convertible पर कब्जा किए बिना Lambdas (बंद प्रकार द्वारा परिभाषित एक गैर-स्पष्ट रूपांतरण फ़ंक्शन द्वारा)।

एफसीडी यह निर्दिष्ट नहीं करता कि कौन सी भाषा उस फ़ंक्शन पॉइंटर प्रकार के फ़ंक्शन प्रकार को जोड़ती है, इसलिए यदि आपको इस फ़ंक्शन पॉइंटर को सी फ़ंक्शंस में पास करने की आवश्यकता है, तो C++ फ़ंक्शंस और सी फ़ंक्शंस के कॉलिंग कन्वेंशन को होना आवश्यक है वही। मेरा मानना ​​है कि विंडोज़ पर, हालांकि यह मामला है। तो तुम 5.1.2/6 पर Windows API कार्यों

typedef void(*callbackType)(void *userData); 
extern "C" void someCFunction(callbackType callback); 

int main() { 
    someCFunction([](void *userData) { /* ... */ }); 
} 

FCD शब्दों के लैम्ब्डा पारित करने के लिए सक्षम होना चाहिए:

कोई लैम्ब्डा पर कब्जा के साथ एक लैम्ब्डा अभिव्यक्ति के लिए बंद करने के प्रकार एक सार्वजनिक गैर आभासी है गैर-स्पष्ट कॉन्स्ट रूपांतरण फ़ंक्शन को पॉइंटर पर समान पैरामीटर और रिटर्न प्रकार को बंद करने के प्रकार के फ़ंक्शन कॉल ऑपरेटर के रूप में कार्य करने के लिए। इस रूपांतरण फ़ंक्शन द्वारा लौटाए गए मान को उस फ़ंक्शन का पता दिया जाएगा, जब इसे लागू किया जाता है, तो बंद करने के प्रकार के फ़ंक्शन कॉल ऑपरेटर को आविष्कार करने के समान ईएफएफ ईटीटी होता है।

मुझे लगता है कि अंतिम स्टैंडर्ड एक नोट है कि कहते हैं, सी लिंकेज समारोह संकेत और सी ++ लिंकेज समारोह संकेत दोनों को ही रूपांतरण समारोह है कि वहाँ सी समारोह संकेत करने के लिए परिवर्तनीयता के रूप में इस कार्यक्षमता के लक्ष्य में से एक है होना चाहिए।

2

कोई विशेष कारण नहीं है कि इसे लैम्ब्स को कैप्चर करने के लिए विस्तारित नहीं किया जाना चाहिए। इसके लिए कुछ गतिशील कोड पीढ़ी की आवश्यकता होती है, लेकिन यह कंपाइलर लेखकों की बुद्धि से परे नहीं होनी चाहिए, और यह पुराने सी एपीआई के साथ परिमाण को आसान बनाने के आदेशों के साथ अंतःक्रिया करेगा - बिना किसी शून्य के * के माध्यम से पैरामीटर पारित करने की आवश्यकता नहीं है (जो सभी नहीं एपीआई भी पेशकश करते हैं)।

+1

समस्या गतिशील कोड जनरेशन नहीं है, यह गतिशील कोड सफाई है। उस कोड को साफ करने के लिए आपको भाषा-स्तर जीसी होना होगा। – Puppy

+2

सी ++ में किसी और चीज से कहीं ज्यादा नहीं। एक thunk के लिए एक साझा_ptr पर्याप्त होगा। – DrPizza

1

एक पर कब्जा कम लैम्ब्डा का रूपांतरण से समारोह सूचक परिणामों की भाषा लिंकेज सी ++ 11 मानक में निर्दिष्ट नहीं किया गया था लेकिन defect report 1557 में संबोधित किया गया था कहते हैं जो:

5.1.2 [expr .prim.lambda] अनुच्छेद 6 बंद प्रकार के रूपांतरण फ़ंक्शन के फ़ंक्शन प्रकार की भाषा लिंक निर्दिष्ट नहीं करता है।

और संकल्प था कि भाषा लिंकेज सी ++ होना चाहिए:

कोई लैम्ब्डा पर कब्जा के साथ एक लैम्ब्डा अभिव्यक्ति के लिए बंद करने के प्रकार के लिए एक सार्वजनिक गैर आभासी गैर स्पष्ट स्थिरांक रूपांतरण कार्य है सी ++ भाषा संबंध (7.5 [dcl.link]) के साथ काम करने के लिए सूचक। बंद पैरामीटर और रिटर्न प्रकार को बंद करने के प्रकार के फ़ंक्शन कॉल ऑपरेटर के रूप में रखना। मान दिया ...

हम मसौदा सी ++ 14 मानक में इस भाषा का दर्जा है, क्योंकि DRWP ऐसा लगता है इस के लिए सी ++ 11 लागू नहीं होता पा सकते हैं,।

+0

ग्रेट फाइंड। लेकिन अगर यह सी ++ 11 के जीवनकाल के दौरान उठाया गया और स्वीकार किया गया दोष था, निश्चित रूप से इसका मतलब है कि यह निश्चित रूप से ** ** सी ++ 11 पर लागू होता है? –

+0

@underscore_d अगर हम [वर्तमान सक्रिय समस्या सूची] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html) देखते हैं जो 'डीआरडब्लूपी' जैसी शर्तों को परिभाषित करता है : 'एक डीआर मुद्दा जिसका संकल्प वर्तमान कार्य पत्र में दर्शाया गया है। वर्किंग पेपर मानक के भविष्य के संस्करण के लिए एक मसौदा है। 'जहां तक ​​मैं कह सकता हूं कि यह सी ++ 14 पर लागू होता है सी ++ 11 नहीं। –