2011-08-26 15 views
6

मैं के साथ सी ++ 11 के आसपास खेल रहा हूँ अभी और कॉलबैक SQLite के रूप में एक लैम्ब्डा उपयोग करने के साथ निम्न समस्या पाया। लैम्ब्डा के अंदर एक वेक्टर चर को कैप्चर करते समय, मुझे यह कहते हुए एक त्रुटि मिलती है कि हस्ताक्षर मेल नहीं खाते हैं। (बजाय [&ret][], और अंदर ret का उपयोग नहीं) लैम्ब्डा में कि चर का उपयोग कर के बिना, यह ठीक काम करता है।कैम्बेबल चर के साथ/बिना लैम्ब्डा के बीच हस्ताक्षर अंतर?

vector<SomeClass> ret; 
char *err = nullptr; 
int res = sqlite3_exec(db, 
         "some sql query, doesn't matter", 
         [&ret](void *unused, int argc, char **argv, char **columnName) -> int 
         { 
          ret.push_back(SomeClass()); 
          return 0; 
         }, 
         nullptr, 
         &err); 

यह वह जगह है त्रुटि मैं:

cannot convert 'TestClass::testMethod()::<lambda(void*, int, char**, char**)>' to 'int (*)(void*, int, char**, char**)' for argument '3' to 'int sqlite3_exec(sqlite3*, const char*, int (*)(void*, int, char**, char**), void*, char**)' 

जीसीसी संस्करण है "जीसीसी (XvidVideo.RU - जीसीसी 4.6.1 i686-पीसी-mingw32) 4.6.1 20,110,625 (प्री-रिलीज़)" पर विंडोज।

क्यों यह एक फर्क पड़ता है?

+0

मैं दृश्य स्टूडियो 2010 संकलक के साथ एक ही बात कोशिश कर रहा हूँ और यह पसंद नहीं करता है या तो लैम्ब्डा के रूप ... किसी को भी अगर यह VS2010 impl में एक ज्ञात बग है पता है? –

उत्तर

6

केवल कैप्चरलेस लैम्बडा को पॉइंटर्स में फ़ंक्शन में परिवर्तित किया जा सकता है, और, कंपाइलर डायग्नोस्टिक के आधार पर, आपके sqlite3_exec ऐसे पॉइंटर, int (*)(void*, int, char**, char**) की अपेक्षा करता है।

के शब्दों में §5.1.2 [expr.prim.lambda]/6

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

+0

समझ में आता है। सिर्फ यह जानना चाहता था कि क्या मैं इसे किसी भी तरह से कैप्चर किए गए चर के साथ हल कर सकता हूं। (। इस विशेष मामले में मैं अपने उद्देश्यों के लिए पाठ्यक्रम उपयोग SQLite के कॉलबैक चर के कर सकते हैं) – AndiDog

+0

@AndiDog मैं तुम्हें चाहते हैं अनुमान लगा रहा हूँ सी पुस्तकालयों के लिए इतने सारे सी ++ कॉलबैक का रास्ता तय करना है: एक गैर-सदस्य या स्थिर सदस्य समारोह है कि कुछ 'शून्य * 'के आधार पर वास्तव में कॉल करने के लिए क्या पता चलता है। – Cubbi

+2

हाँ, 'sqlite3_exec' मुझे कॉलबैक करने के लिए' एक 'शून्य * पारित करने के लिए अनुमति देता है, मैं सिर्फ naively सोचा था इस के साथ सी ++ 11 आसान किया जा सकता है। – AndiDog

1

क्या कॉलबैक के लिए 1 तर्क का उपयोग के बारे में?

vector<SomeClass> ret; 
char *err = nullptr; 
int res = sqlite3_exec(db, 
         "some sql query, doesn't matter", 
         [](void *ctx, int argc, char **argv, char **columnName) -> int 
         { 
          static_cast<vector<SomeClass>*>(ctx)->push_back(SomeClass()); 
          return 0; 
         }, 
         &ret, 
         &err); 
संबंधित मुद्दे