एमएसल्टर्स नोट करते हैं कि "गैर-कैप्चरिंग लैम्ब्डा को पॉइंटर-टू-फ़ंक्शन में परिवर्तित किया जा सकता है।" इसका क्या मतलब है? लैम्ब्डा ऑब्जेक्ट फ़ंक्शन पैरामीटर प्रकार के लिए पॉइंटर से मेल खाता है।
लैम्ब्डा प्रकार को पॉइंटर-टू-फ़ंक्शन में अनुवाद करना मुश्किल है। एक अनुपालन कार्यान्वयन पर मेरा प्रयास यहां है। यह थोड़ा हैकिश है।
#include <type_traits>
template< typename fn >
struct ptmf_to_pf;
template< typename r, typename c, typename ... a >
struct ptmf_to_pf< r (c::*) (a ...) const >
{ typedef r (* type)(a ...); };
// Use SFINAE to hide function if lambda is not convertible to function ptr.
// Only check that the conversion is legal, it never actually occurs.
template< typename lambda >
typename std::enable_if< std::is_constructible<
typename ptmf_to_pf< decltype(&lambda::operator()) >::type,
lambda >::value >::type
f(lambda arg) {
arg("hello ");
arg("world\n");
}
#include <iostream>
int main() {
int x = 3;
f([](char const *s){ std::cout << s; }); // OK
f([=](char const *s){ std::cout << s; }); // OK
f([=](char const *s){ std::cout << s << x; }); // error
}
यह सीधा तर्क के रूप में कार्य संकेत को स्वीकार नहीं करेगा, क्योंकि टेम्पलेट पैरामीटर एक functor को हल करने की जरूरत है। आप इसे ptmf_to_pf
के लिए विशेषज्ञता प्रदान करके ऐसा कर सकते हैं जो फ़ंक्शन प्रकारों के लिए पॉइंटर स्वीकार करता है।
इसके अलावा, जैसा कि डेमो दिखाता है, यह लैम्बडा स्वीकार नहीं करेगा जो मूल्य के साथ-साथ संदर्भ द्वारा कुछ भी कैप्चर करता है। प्रतिबंध को इतना विशिष्ट बनाने के लिए सी ++ में कोई रास्ता नहीं है।
जब तक क्लोजर ऑब्जेक्ट आपके फ़ंक्शन को हिट करता है, तब तक यह पहले से ही बनाया जा चुका है, और आपको पता नहीं है कि इसके गले के अंदर क्या है, क्योंकि ये निजी हैं। लेकिन यदि आप सोच रहे थे, तो लैम्ब्डा निश्चित रूप से * * के बाद कुछ भी नहीं ले सकता है, और विशेष रूप से * आपके * फ़ंक्शन 'f' के भीतर से कुछ भी नहीं। –
यह व्यर्थ होगा, क्योंकि मूल्य के आधार पर पॉइंटर को कैप्चर करना उतना ही खतरनाक है जितना संदर्भ को कैप्चर करना। –
@BenVoigt यह सही है। – log0