दिलचस्प पोस्ट
किसी सर्वर पर एक छवि के रूप में एक HTML5 कैनवास कैसे सहेज सकता है? Entity Framework 6 का उपयोग कर रिकॉर्ड कैसे अपडेट करें? वर्तमान गतिविधि से रूट दृश्य प्राप्त करें शरीर का 100% ब्राउज़र ऊँचाई बनाएं Mysqli में कई मूल्यों का सबसे अच्छा तरीका है? लिनक्स पर सभी फ़ोल्डर्स और फाइलों को लोअरकेस में कैसे बदलना है? Xcode 8 / स्विफ्ट 3.0 में पुश नोटिफिकेशन के लिए पंजीकरण करना है? जीडीबी के साथ मानक कंटेनर (एसटीडी :: नक्शा) का निरीक्षण करना एआरएम थंब 2 के लिए एक कुशल पूर्णांक वर्ग रूट एल्गोरिथ्म की तलाश में एंड्रॉइड: एनीमेशन का विस्तार / संक्षिप्त करें मुझे एक सी मॉलोक दावा करने की विफलता क्यों मिलती है? javafx listview और treeview नियंत्रण सही ढंग से repainted नहीं हैं पाठ क्षेत्र का चयन होने पर एक UITableView स्क्रॉल करना रंग के साथ UIBarButtonItem? एक प्रक्रिया SIGABRT (संकेत 6) कब मिलता है?

फ़ंक्शन संकेतक के रूप में कैप्चर के साथ सी ++ लैम्ब्डा

मैं सी ++ लैम्ब्डास के साथ खेल रहा था और फ़ंक्शन पॉइंटर के लिए उनका अंतर्निहित रूपांतरण था। मेरा प्रारंभिक उदाहरण उन्हें एफटीवी समारोह के लिए कॉलबैक के रूप में उपयोग कर रहा था। उम्मीद है कि यह काम करता है

#include <ftw.h> #include <iostream> using namespace std; int main() { auto callback = [](const char *fpath, const struct stat *sb, int typeflag) -> int { cout << fpath << endl; return 0; }; int ret = ftw("/etc", callback, 1); return ret; } 

इसे कैप्चर करने के लिए संशोधित करने के बाद:

 int main() { vector<string> entries; auto callback = [&](const char *fpath, const struct stat *sb, int typeflag) -> int { entries.push_back(fpath); return 0; }; int ret = ftw("/etc", callback, 1); for (auto entry : entries ) { cout << entry << endl; } return ret; } 

मुझे संकलक त्रुटि मिली:

 error: cannot convert 'main()::<lambda(const char*, const stat*, int)>' to '__ftw_func_t {aka int (*)(const char*, const stat*, int)}' for argument '2' to 'int ftw(const char*, __ftw_func_t, int)' 

कुछ पढ़ने के बाद मैंने सीखा है कि कब्जे का उपयोग करने वाले लैम्ब्डा को फ़ंक्शन पॉइंटर में परस्पर रूप से परिवर्तित नहीं किया जा सकता है

क्या इसके आसपास कोई कार्य है? क्या यह तथ्य है कि वे "निहित" नहीं हो सकते हैं इसका मतलब यह है कि वे "स्पष्ट रूप से" रूपांतरित कर सकते हैं? (मैंने सफलता के बिना कास्टिंग की कोशिश की) काम करने वाले उदाहरण को संशोधित करने का एक साफ तरीका क्या होगा, ताकि मैं लैम्ब्दास का इस्तेमाल करते हुए किसी वस्तु को प्रविष्ट कर सकूं?

वेब के समाधान से एकत्रित समाधान "फ़ंक्शन संकेतक के रूप में कैप्चर के साथ सी ++ लैम्ब्डा"

लम्ब्दास को कैप्चर करने के बाद से एक राज्य को संरक्षित करने की आवश्यकता है, वास्तव में एक सरल "समाधान" नहीं है, क्योंकि ये केवल साधारण कार्य नहीं हैं फ़ंक्शन पॉइंटर के बारे में बात यह है कि यह एक एकल, वैश्विक फ़ंक्शन को इंगित करता है, और इस जानकारी के लिए किसी राज्य के लिए कोई स्थान नहीं है।

निकटतम समाधान (जो अनिवार्य रूप से राज्यपूर्णता को अस्वीकार कर देता है) कुछ प्रकार के वैश्विक चर प्रदान करना है जो आपके लैम्ब्डा / फ़ंक्शन से उपयोग किया जाता है। उदाहरण के लिए, आप एक पारंपरिक मटकाकार ऑब्जेक्ट बना सकते हैं और इसे एक स्थैतिक सदस्य फ़ंक्शन दे सकते हैं, जो कि कुछ अद्वितीय (वैश्विक / स्थैतिक) उदाहरण को दर्शाता है।

लेकिन यह लम्ब्दास पर कब्जा करने के पूरे उद्देश्य को पराजित करने का एक प्रकार है।

मैं बस इस समस्या में भाग गया

कोड लम्ब्डा कब्जा के बिना ठीक संकलित करता है, लेकिन लैम्ब्डा कैप्चर के साथ एक प्रकार की रूपांतरण त्रुटि है।

सी ++ 11 के साथ समाधान std::function का उपयोग करना है आप boost::function उपयोग भी कर सकते हैं (जो वास्तव में बहुत तेजी से चलाता है)। उदाहरण कोड – बदल दिया गया है ताकि यह संकलन करे, gcc 4.7.1 साथ संकलित किया जाए:

 #include <iostream> #include <vector> #include <functional> using namespace std; int ftw(const char *fpath, std::function<int (const char *path)> callback) { return callback(fpath); } int main() { vector<string> entries; std::function<int (const char *fpath)> callback = [&](const char *fpath) -> int { entries.push_back(fpath); return 0; }; int ret = ftw("/etc", callback); for (auto entry : entries ) { cout << entry << endl; } return ret; } 

लैम्ब्डा फ़ंक्शंस बहुत सुविधाजनक हैं और एक कोड को कम करते हैं। मेरे मामले में मुझे समानांतर प्रोग्रामिंग के लिए लैंबडा की जरूरत थी। लेकिन इसमें कैप्चरिंग और फ़ंक्शन पॉइंटर्स की आवश्यकता है मेरा समाधान यहाँ है लेकिन उन चर के दायरे से सावधानी बरतें जिन्हें आपने कब्जा कर लिया था।

 template<typename Tret, typename T> Tret lambda_ptr_exec(T* v) { return (Tret) (*v)(); } template<typename Tret = void, typename Tfp = Tret(*)(void*), typename T> Tfp lambda_ptr(T& v) { return (Tfp) lambda_ptr_exec<Tret, T>; } 

उदाहरण

 int a = 100; auto b = [&]() { a += 1;}; void (*fp)(void*) = lambda_ptr(b); fp(&b); 

रिटर्न वैल्यू के साथ उदाहरण

 int a = 100; auto b = [&]() {return a;}; int (*fp)(void*) = lambda_ptr<int>(b); fp(&b); 

हे – काफी पुरानी सवाल है, लेकिन अभी भी …

 #include <iostream> #include <vector> #include <functional> using namespace std; // We dont try to outsmart the compiler... template<typename T> int ftw(const char *fpath, T callback) { return callback(fpath); } int main() { vector<string> entries; // ... now the @ftw can accept lambda int ret = ftw("/etc", [&](const char *fpath) -> int { entries.push_back(fpath); return 0; }); // ... and function object too struct _ { static int lambda(vector<string>& entries, const char* fpath) { entries.push_back(fpath); return 0; } }; ret = ftw("/tmp", bind(_::lambda, ref(entries), placeholders::_1)); for (auto entry : entries ) { cout << entry << endl; } return ret; } 

कैप्चरिंग लैम्ब्डा को फ़ंक्शन पॉइंटर में कनवर्ट करने के लिए एक तेज़ तरीका है, लेकिन इसका उपयोग करते समय आपको सावधान रहना होगा:

https://codereview.stackexchange.com/questions/79612/c-ifying-a-capturing-lambda

आपका कोड तब इस तरह दिखेगा (चेतावनी: मस्तिष्क संकलन):

 int main() { vector<string> entries; auto const callback = cify<int(*)(const char *, const struct stat*, int)>([&](const char *fpath, const struct stat *sb, int typeflag) -> int { entries.push_back(fpath); return 0; }); int ret = ftw("/etc", callback, 1); for (auto entry : entries ) { cout << entry << endl; } return ret; } 

दृश्य स्टूडियो 2010 में मुझे एक समान समस्या थी, और मुझे एक वैकल्पिक हल मिला मुझे यकीन नहीं है कि यह कैप्चर के साथ काम करेगा क्योंकि मैंने उस परिदृश्य का परीक्षण नहीं किया था, लेकिन मुझे नहीं पता कि यह क्यों नहीं होगा।

मुझे पता है कि यह काम नहीं करता है, और मैं देखूंगा कि मैं इसे ठीक कर सकता हूं।

यहां एक उत्तर मिला: http://meh.schizofreni.co/programming/magic/2013/01/23/function-pointer-from-lambda.html

यह lambda pointer को void* कनवर्ट करता है और जब ज़रूरत होती है तो उसे वापस कन्वर्ट करता है।

  1. void* :

    ऑटो voidfunction = new decltype (to_function (लैम्ब्डा)) (to_function (लैम्ब्डा));

  2. void* से:

    ऑटो फंक्शन = स्टेटिक_कास्ट <std :: function *> (voidfunction);