जवाबों:
व्यक्तिगत लंबोदर को संकलक द्वारा विभिन्न वर्गों में अनुवादित किया जाता है। उदाहरण के लिए, lambda1 की परिभाषा इसके बराबर है:
class SomeCompilerGeneratedTypeName {
public:
SomeCompilerGeneratedTypeName(...) { // Capture all the required variables here
}
void operator()(T& arg) const {
// ...
}
private:
// All the captured variables here ...
};
इसलिए, संकलक द्वारा दो अलग-अलग प्रकार उत्पन्न होते हैं, जो एक प्रकार की असंगति का कारण बनता है auto lambda = condition ? lambda1 : lambda2;
निम्नलिखित काम करेगा:
auto lambda = condition ? std::function<void(T&)>(lambda1) : std::function<void(T&)>(lambda2);
यह उजागर करने के लिए कि दोनों लंबदा वास्तव में अलग-अलग प्रकार के हैं, हम <typeinfo>
मानक पुस्तकालय और typeid
ऑपरेटर से उपयोग कर सकते हैं । लैम्ब्डा पॉलिमॉर्फिक प्रकार नहीं हैं, इसलिए मानक गारंटी देता है कि 'टाइपिड' ऑपरेटर का संकलन समय पर किया जाता है। इससे पता चलता है कि निम्नलिखित उदाहरण वैध है भले ही RTTI अक्षम हो:
#include <iostream>
#include <typeinfo>
int main()
{
struct T {
};
auto lambda1 = [&](T& arg) {
return;
};
auto lambda2 = [&](T& arg) {
return;
};
std::cout << typeid(lambda1).name() << "/" << typeid(lambda1).hash_code() << std::endl;
std::cout << typeid(lambda2).name() << "/" << typeid(lambda2).hash_code() << std::endl;
return 0;
}
कार्यक्रम का आउटपुट (GCC 8.3 के साथ, Gobolt पर देखें ):
Z4mainEUlRZ4mainE1TE_/7654536205164302515
Z4mainEUlRZ4mainE1TE0_/10614161759544824066
SomeCompilerGeneratedTypeName1
औरSomeCompilerGeneratedTypeName2
उत्सुकता से, अगर लंबोदर कैद-कम हैं, तो ऑपरेटर +
चाल को नियोजित किया जा सकता है:
auto lambda1 = [](int arg) { ... };
auto lambda2 = [](int arg) { ... };
auto lambda = condition ? +lambda1 : +lambda2; // This compiles!
lambda(2019);
यह काम करता है, क्योंकि +
लंबो को एक फ़ंक्शन पॉइंटर में बदल देगा, और दोनों फ़ंक्शन पॉइंटर्स का एक ही प्रकार (कुछ ऐसा है void (*)(int)
) होगा।
जीसीसी और क्लैंग (लेकिन एमएसवीसी के साथ नहीं) के साथ, +
छोड़ा जा सकता है, लैम्ब्डा को अभी भी फ़ंक्शन पॉइंटर्स में परिवर्तित किया जाएगा।
यह संकलित नहीं करता है क्योंकि प्रत्येक लंबोदर के पास एक अद्वितीय प्रकार है, इसके लिए एक सामान्य प्रकार नहीं है ?:
।
आप उन्हें लपेट सकते हैं std::function<void(T&)>
, जैसे
auto lamba1 = [&](T& arg) {
...
};
auto lambda2 = [&](T& arg) {
...
};
auto lambda = condition ? std::function(lambda1) : lambda2; // C++17 class template deduction