में परिवर्तित किया जा सकता है मेरे पास कुछ कोड है जो एक जेआईटी विचार के लिए असेंबली उत्पन्न करता है जिस पर मैं काम कर रहा हूं। मैं फ़ंक्शन प्रकार का विश्लेषण करके कॉल उत्पन्न करने के लिए मेटा-प्रोग्रामिंग का उपयोग करता हूं और फिर इसे कॉल करने के लिए सही असेंबली उत्पन्न करता हूं। मैं हाल ही में लैम्ब्डा समर्थन जोड़ना चाहता था, और लैम्बडास के दो संस्करण हैं, गैर-कैप्चरिंग (सामान्य __cdecl फ़ंक्शन कॉल) और कैप्चरिंग (__thiscall, लैम्ब्डा ऑब्जेक्ट के साथ सदस्य-फ़ंक्शन कॉल संदर्भ के रूप में)।पता लगाएं कि सी ++ लैम्ब्डा को फ़ंक्शन पॉइंटर
__thiscall थोड़ा महंगा है इसलिए जब भी संभव हो मैं इसे टालना चाहूंगा, और मैं लैम्ब्डा प्रकार के आधार पर विभिन्न कॉल जनरेशन फ़ंक्शंस का उपयोग करने से बचना चाहूंगा।
मैंने टेम्पलेट्स और एसएफआईएनएई के माध्यम से लैम्ब्डा प्रकार का पता लगाने के कई तरीकों की कोशिश की और सभी असफल रहे।
गैर-कैप्चरिंग लैम्बडास में ::operator function_type*
है जो कि उन्हें फ़ंक्शन पॉइंटर्स में बदलने के लिए उपयोग कर सकते हैं, जबकि लैम्बडास कैप्चरिंग नहीं करते हैं।
प्रासंगिक सी ++ कल्पना: http://en.cppreference.com/w/cpp/language/lambda
कोई भी विचार?
संपादित मैं एक समाधान है कि बनाम 2013/2015 के लिए काम करता है करना चाहते हैं, जीसीसी और बजना
टेस्ट कोड इस प्रकार
#include <utility>
//this doesn't work
template < class C, class T >
struct HasConversion {
static int test(decltype(std::declval<C>().operator T*, bool()) bar) {
return 1;
}
static int test(...) {
return 0;
}
};
template <class C>
void lambda_pointer(C lambda) {
int(*function)() = lambda;
printf("Lambda function: %p without context\n", function);
}
template <class C>
void lambda_pointer_ctx(C lambda) {
int(C::*function)() const = &C::operator();
void* context = λ
printf("Lambda function: %p with context: %p\n", function, context);
}
int main() {
int a;
auto l1 = [] {
return 5;
};
auto l2 = [a] {
return a;
};
//non capturing case
//works as expected
lambda_pointer(l1);
//works as expected (ctx is meaningless and not used)
lambda_pointer_ctx(l1);
//lambda with capture (needs context)
//fails as expected
lambda_pointer(l1);
//works as expected (ctx is a pointer to class containing the captures)
lambda_pointer_ctx(l1);
/*
//this doesn't work :<
typedef int afunct() const;
HasConversion<decltype(l1), afunct>::test(0);
HasConversion<decltype(l2), afunct>::test(0);
*/
return 0;
}
आप लैम्ब्डा के हस्ताक्षर को जानते हो? यदि आप ऐसा करते हैं तो यह थोड़ा क्लीनर बनाता है। – Yakk
यदि आप हस्ताक्षर जानते थे, तो आप 'std :: is_assignable {}', या, अपने मामले में 'std :: is_assignable {} '' typedef void afunct (int) के साथ; ' –
नहीं, इसे किसी भी हस्ताक्षर के लिए काम करना है - मैं –