Nội dung bài viết
Đăng ký học lập trình C++
Tại STDIO bạn được dạy nền tảng lập trình tốt nhất.
Đăng ký học
C++14 hỗ trợ nhiều hơn cho Lambda, có sự can thiệp nhiều hơn của trình biên dịch trong việc hiện thực 1 biểu thức Lambda, và nó được gọi là Generic Lambda. Ở bài viết này ta sẽ tìm hiểu về Generic Lambda và cách sử dụng.

Giới thiệu

Trong C++11 - Lambda đã được hỗ trợ và giúp giải quyết được 1 vấn đề tồn đọng lâu nay đó là, hàm chỉ được gọi tại 1 chỗ thì định nghĩa hàm tại chỗ đó thay vì định nghĩa 1 hàm dùng chung nhưng thật ra chỉ gọi ở 1 vị trí trong codes (cần lưu ý là Lambda khác với Inline Functions Trong C++).

Với C++14, Lambda đã làm nhiều hơn như vậy, không đơn thuần là nó là cách thức gõ code và mã của nó khi biên dịch sẽ được tạo ra ngay, mà nó có vai trò như 1 template, và vị trí nào sử dụng Lambda này với các kiểu dữ liệu tương ứng thì trình biên dịch sẽ sinh ra hàm tương ứng kiểu dữ liệu đó.

Tiền đề bài viết

Sau bài viết C++14 - Từ Khóa auto Và Khả Năng Tự Động Nhận Kiểu Khi Hiện Thực Một Hàm tôi thấy để bổ sung đầy đủ hơn cho auto thì cần chia sẻ thêm điều này nữa.

Đối tượng hướng đến

Dành cho các độc giả có hứng thú với điều mới lạ nhưng cần thiết phải nắm được C++11 ở mức cơ bản nhất là phần C++14 - Từ Khóa auto Và Khả Năng Tự Động Nhận Kiểu Khi Hiện Thực Một HàmC++11 - Lambda.

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.

Bạn 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 làm ta 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, ta 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.

THẢO LUẬN