लैम्ब्डा के भाव, यहां तक कि कैप्चर किए गए, एक फ़ंक्शन पॉइंटर (सदस्य फ़ंक्शन के लिए पॉइंटर) के रूप में संभाला जा सकता है।
यह मुश्किल है क्योंकि एक लंबोदर अभिव्यक्ति एक साधारण कार्य नहीं है। यह वास्तव में एक ऑपरेटर () के साथ एक वस्तु है।
जब आप रचनात्मक हों, तो आप इसका उपयोग कर सकते हैं! Std :: function की शैली में "फ़ंक्शन" वर्ग के बारे में सोचें। यदि आप ऑब्जेक्ट को सेव करते हैं तो आप फंक्शन पॉइंटर का भी उपयोग कर सकते हैं।
फ़ंक्शन पॉइंटर का उपयोग करने के लिए, आप निम्न का उपयोग कर सकते हैं:
int first = 5;
auto lambda = [=](int x, int z) {
return x + z + first;
};
int(decltype(lambda)::*ptr)(int, int)const = &decltype(lambda)::operator();
std::cout << "test = " << (lambda.*ptr)(2, 3) << std::endl;
एक वर्ग बनाने के लिए जो "std :: function" की तरह काम करना शुरू कर सकता है, पहले आपको ऑब्जेक्ट और फंक्शन पॉइंटर को स्टोर करने की तुलना में एक क्लास / स्ट्रक्चर की आवश्यकता होती है। इसे निष्पादित करने के लिए आपको एक ऑपरेटर () की आवश्यकता है:
// OT => Object Type
// RT => Return Type
// A ... => Arguments
template<typename OT, typename RT, typename ... A>
struct lambda_expression {
OT _object;
RT(OT::*_function)(A...)const;
lambda_expression(const OT & object)
: _object(object), _function(&decltype(_object)::operator()) {}
RT operator() (A ... args) const {
return (_object.*_function)(args...);
}
};
इसके साथ अब आप कैप्चर किए गए, गैर-कैप्चर किए गए लैम्ब्डा चला सकते हैं, जैसे आप मूल का उपयोग कर रहे हैं:
auto capture_lambda() {
int first = 5;
auto lambda = [=](int x, int z) {
return x + z + first;
};
return lambda_expression<decltype(lambda), int, int, int>(lambda);
}
auto noncapture_lambda() {
auto lambda = [](int x, int z) {
return x + z;
};
return lambda_expression<decltype(lambda), int, int, int>(lambda);
}
void refcapture_lambda() {
int test;
auto lambda = [&](int x, int z) {
test = x + z;
};
lambda_expression<decltype(lambda), void, int, int>f(lambda);
f(2, 3);
std::cout << "test value = " << test << std::endl;
}
int main(int argc, char **argv) {
auto f_capture = capture_lambda();
auto f_noncapture = noncapture_lambda();
std::cout << "main test = " << f_capture(2, 3) << std::endl;
std::cout << "main test = " << f_noncapture(2, 3) << std::endl;
refcapture_lambda();
system("PAUSE");
return 0;
}
यह कोड VS2015 के साथ काम करता है
अद्यतन 04.07.17:
template <typename CT, typename ... A> struct function
: public function<decltype(&CT::operator())(A...)> {};
template <typename C> struct function<C> {
private:
C mObject;
public:
function(const C & obj)
: mObject(obj) {}
template<typename... Args> typename
std::result_of<C(Args...)>::type operator()(Args... a) {
return this->mObject.operator()(a...);
}
template<typename... Args> typename
std::result_of<const C(Args...)>::type operator()(Args... a) const {
return this->mObject.operator()(a...);
}
};
namespace make {
template<typename C> auto function(const C & obj) {
return ::function<C>(obj);
}
}
int main(int argc, char ** argv) {
auto func = make::function([](int y, int x) { return x*y; });
std::cout << func(2, 4) << std::endl;
system("PAUSE");
return 0;
}