क्या कैप्चरलेस लैम्ब्डा मानक द्वारा खाली होने की गारंटी है?


12

मैं एक टेम्पलेट फ़ंक्शन में अन्य लैम्ब्डा से खाली (कैप्चरलेस) लैम्ब्डा की पहचान करने का तरीका खोज रहा हूं। मैं वर्तमान में C ++ 17 का उपयोग कर रहा हूं, लेकिन मैं C ++ 20 उत्तरों के लिए भी उत्सुक हूं।

मेरा कोड इस तरह दिखता है:

template<typename T>
auto func(T lambda) {
    // The aguments of the lambdas are unknown

    if constexpr (/* is captureless */) {
        // do stuff
    }
}

क्या यह सी ++ मानक (17 या 20) की गारंटी देता है कि एक कैप्चरलेस लैम्ब्डा, जो एक फ़ंक्शन पॉइंटर के लिए परिवर्तनीय है, क्या std::is_emptyउपज को भी सच कर देगा?

इस कोड को एक उदाहरण के रूप में लें:

auto a = []{}; // captureless
auto b = [c = 'z']{}; // has captures

static_assert(sizeof(a) == sizeof(b)); // Both are the same size
static_assert(!std::is_empty_v<decltype(b)>); // It has a `c` member
static_assert(std::is_empty_v<decltype(a)>); // Passes. It is guaranteed?

जीवंत उदाहरण


2
यदि आप केवल गैर-टेम्प्लेट लैम्ब्डा के बारे में परवाह करते हैं, तो आप SFINAE का उपयोग करके यह जांच सकते हैं कि फ़ंक्शन पॉइंटर ( +lambda) में रूपांतरण अच्छी तरह से बनता है या नहीं।
होलीब्लैकैट

@HolyBlackCat मैंने इसके बारे में सोचा था, लेकिन जहां तक ​​मुझे याद है, MSVC ने अनुमति नहीं दी है क्योंकि उन्होंने रूपांतरण ऑपरेटर को ओवरलोड किया था।
गिलाउम रेसिकोट

@GuillaumeRacicot MS सभी उपलब्ध कॉलिंग सम्मेलनों के लिए एक अलग रूपांतरण ऑपरेटर को उजागर करता है। बस एक चुनें और लैम्ब्डा को एक तुलनीय फ़ंक्शन पॉइंटर में बदलने का प्रयास करें, और जांचें कि क्या वह सफल होता है या विफल।
रेमी लेबेऊ

+यहाँ काम करने लगता है
होलीब्लैकैट

जवाबों:


13

नहीं, वास्तव में, मानक स्पष्ट रूप से लैम्ब्डा के लिए एक आकार की अनुमति देता है जो उनके घोषणा के साथ लाइन नहीं करता है। [expr.prim.lambda.closure] / 2 राज्य

क्लोजर टाइप को सबसे छोटे ब्लॉक स्कोप, क्लास स्कोप या नेम्स्पेस स्पेस में घोषित किया जाता है, जिसमें लैम्बडा-एक्सप्रेशन होता है। [नोट: यह बंद प्रकार ([basic.lookup.argdep)) से जुड़े नामस्थान और वर्गों के समूह को निर्धारित करता है। लंबो-डिक्लेरेटर के पैरामीटर प्रकार इन संबंधित नामस्थानों और वर्गों को प्रभावित नहीं करते हैं। - अंतिम नोट] क्लोजर प्रकार एक कुल प्रकार नहीं है। एक कार्यान्वयन क्लोजर प्रकार को अलग-अलग परिभाषित कर सकता है जो कि नीचे वर्णित है, बशर्ते कि यह कार्यक्रम के अवलोकन योग्य व्यवहार को इसके अलावा अन्य द्वारा न बदले:

  • क्लोजर प्रकार का आकार और / या संरेखण,

  • क्या क्लोजर प्रकार तुच्छ रूप से कॉपी करने योग्य है ([class.prop]), या (2.3)

  • क्या क्लोजर प्रकार एक मानक-लेआउट वर्ग ([class.prop]) है।

एक कार्यान्वयन क्लोजर प्रकार के लिए रेवल्यू रेफरेंस टाइप के सदस्यों को शामिल नहीं करेगा।

जोर मेरा

तो यह कार्यान्वयन को लैम्ब्डा को एक सदस्य देने की अनुमति देता है, भले ही वह कैप्चर-लेस हो। मुझे नहीं लगता कि कोई भी कार्यान्वयन कभी होगा, लेकिन उन्हें कानूनी रूप से ऐसा करने की अनुमति है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.