เหตุผลก็คือ lambdas เป็นวัตถุของฟังก์ชั่นดังนั้นการส่งผ่านไปยังเทมเพลตของฟังก์ชันจะยกตัวอย่างฟังก์ชันใหม่สำหรับวัตถุนั้นโดยเฉพาะ คอมไพเลอร์สามารถ inline โทรแลมบ์เล็กน้อย
สำหรับฟังก์ชั่นในทางกลับกันข้อแม้เก่าใช้: ตัวชี้ฟังก์ชั่นได้รับการส่งผ่านไปยังแม่แบบฟังก์ชั่นและคอมไพเลอร์แบบดั้งเดิมมีปัญหามากมายในการโทรผ่านตัวชี้ฟังก์ชั่น พวกมันสามารถอนุมานตามทฤษฎีได้ แต่ถ้าฟังก์ชันรอบข้างถูกอินไลน์เช่นกัน
เป็นตัวอย่างพิจารณาแม่แบบฟังก์ชั่นต่อไปนี้:
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
เป็นฟังก์ชันหนึ่งได้