कारण यह है कि लंबोदर फ़ंक्शन ऑब्जेक्ट्स हैं इसलिए उन्हें फंक्शन टेम्प्लेट में पास करने से उस ऑब्जेक्ट के लिए विशेष रूप से एक नया फ़ंक्शन इंस्टेंट हो जाएगा। कंपाइलर इस प्रकार तुच्छ रूप से लैम्ब्डा कॉल को इनलाइन कर सकता है।
दूसरी ओर, फ़ंक्शन के लिए, पुराना कैविट लागू होता है: एक फंक्शन पॉइंटर फंक्शन टेम्प्लेट में पास हो जाता है, और कंपाइलर को पारंपरिक रूप से फंक्शन पॉइंटर्स के माध्यम से कॉल को इनलाइन करने में बहुत समस्या होती है। वे सैद्धांतिक रूप से इनबिल्ड हो सकते हैं , लेकिन केवल तभी जब आसपास का फ़ंक्शन भी इनबिल्ट हो।
एक उदाहरण के रूप में, निम्न फ़ंक्शन टेम्पलेट पर विचार करें:
template <typename Iter, typename F>
void map(Iter begin, Iter end, F f) {
for (; begin != end; ++begin)
*begin = f(*begin);
}
इसे लंबोदर के साथ इस तरह बुलाना:
int a[] = { 1, 2, 3, 4 };
map(begin(a), end(a), [](int n) { return n * 2; });
इस तात्कालिकता में परिणाम (कंपाइलर द्वारा निर्मित):
template <>
void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) {
for (; begin != end; ++begin)
*begin = f.operator()(*begin);
}
... संकलक जानता है _some_lambda_type::operator ()
और इनलाइन को तुच्छ रूप से कॉल कर सकता है। (और किसी अन्य लैंबडा के map
साथ फ़ंक्शन को लागू करने से एक नया तात्कालिकता पैदा होगी क्योंकि प्रत्येक लैम्ब्डा का एक अलग प्रकार है।)map
लेकिन जब एक फ़ंक्शन पॉइंटर के साथ बुलाया जाता है, तो इंस्टेंटेशन निम्नानुसार दिखता है:
template <>
void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) {
for (; begin != end; ++begin)
*begin = f(*begin);
}
… और यहां f
प्रत्येक कॉल के लिए एक अलग पते की ओर इशारा किया गया है map
और इस तरह कंपाइलर इनलाइन कॉल नहीं कर सकता है f
जब तक कि आसपास के कॉल को map
भी इनलेट नहीं किया गया है ताकि कंपाइलर f
एक विशिष्ट फ़ंक्शन को हल कर सके।