Nhắc lại Lambda trong C++11
Trong C++11, biểu thức Lambda được định nghĩa như sau
#include <iostream> int main() { auto max = [](int a, int b) { return a > b ? a : b; }; std::cout << max(1, 2); return 0; }
Dòng 5, 6, 7 là biểu hiện của biểu thức Lambda. Đọc thêm bài C++11 - Lambda để nắm lại kiến thức về biểu thức này.
Vấn đề của C++11
Ở C++11, biểu thức Lambda kiểu như sau sẽ không được chấp nhận.
auto max = [](auto a, int b) { return a > b ? a : b; }; std::cout << max(1, 2); std::cout << max(1.2, 5.6);
Trình biên dịch sẽ báo lỗi ở dòng 1 vì auto a
không được C++11 thiết kế chức năng đó, nó không có khả năng biết được a là kiểu gì.
Lambda trong C++14
Ở C++14, Lambda cho phép auto
trong việc truyền tham số, xét ví dụ dưới đây (với C++11 thì không thể, nhưng với C++14 thì có thể).
auto max = [](auto a, int b) { return a > b ? a : b; }; std::cout << max(1, 2); std::cout << max(1.2, 5.6);
Vấn đề sâu hơn là tại sao nó lại có thể biết trước được kiểu dữ liệu để biên dịch? Chắc chắn là không.
Lưu ý dòng 5 và dòng 6, với a
là 1
thì kiểu dữ liệu là int
và với a
là 1.2
thì kiểu dữ liệu sẽ là double
. Điều này liên tưởng đến template Trong C++ và điều liên tưởng này là đúng. Tại thời điểm biên dịch, thì Lambda chưa được biên dịch mà trình biên dịch chỉ "note" lại template của hàm. Cho đến những nơi gọi hàm và chỉ định kiểu cụ thể, trong trường hợp trên là dòng 5 thì 1
chính là kiểu int
và dòng 6 thì 1.2
là kiểu double
, lúc này trình biên dịch mới dựa vào template đó và sinh ra hàm phù hợp.
Lưu ý, điều này chưa áp dụng cho 1 hàm, chưa có Generic Function, nhưng nếu có, có thể template cho hàm không còn tồn tại nữa.