ลูกแกะแต่ละตัวจะถูกแปลเป็นคลาสที่แตกต่างกันโดยคอมไพเลอร์ ตัวอย่างเช่นคำจำกัดความของ 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
ผู้ดำเนินการ แลมบ์ดาไม่ใช่ประเภท polymorphic ดังนั้นมาตรฐานรับประกันว่าตัวดำเนินการ '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