Nội dung
Trong bài viết này, chúng ta sẽ thảo luận về Lambda Functions trong C++11, cách sử dụng Lambda Functions làm Callbacks.
Hàm lambda là gì?
Các hàm lambda là một loại hàm ẩn danh trong C++. Chúng chủ yếu được sử dụng làm callback trong C++. Hàm lambda cũng tương tự như một hàm bình thường, tức là
- Bạn có thể chuyển đối số cho nó
- Nó có thể trả về kết quả
Nhưng nó không có bất kỳ tên định danh nào. Nó chủ yếu được sử dụng khi chúng ta phải tạo các hàm rất nhỏ để truyền hàm callback cho một API khác.
Trước khi đi sâu vào các hàm lambda, hãy tìm hiểu nhu cầu của các hàm lambda là gì.
Sự cần thiết có hàm Lambda
Giả sử, ta có một mảng interger và ta muốn duyệt trên mảng này và in tất cả các giá trị bằng hàm std::for_each với việc sử dụng con trỏ hàm,
#include <iostream>
#include <algorithm>void display(int a){
std::cout<<a<<" ";
}
int main() {
int arr[] = { 1, 2, 3, 4, 5 };
std::for_each(arr, arr + sizeof(arr) / sizeof(int), &display);
std::cout << std::endl;
}
Trong ví dụ trên, ta đã tạo một hàm riêng để đơn giản thực hiện việc hiển thị. Vậy có cách nào ta có thể đạt được yêu cầu của mình và cũng tránh được chi phí xây dưng hàm này không.
Sự trỗi dậy của các hàm Lambda
Để giải quyết điều yêu cầu trên, chúng ta có thể sử dụng các hàm lambda. Hàm lambda là một loại hàm ẩn danh không có bất kỳ tên nào nhưng ta có thể chuyển các đối số và trả về kết quả từ nó. Ví dụ về hàm Lambda như sau,
[](int x) {std::cout<<x<<" ";}
Trong đó,
- [] được sử dụng để truyền các phần tử bên ngoài phạm vi
- (int x) cho thấy đối số x được truyền
Hãy xem lại ví dụ trên với việc sử dụng hàm lambda,
#include <iostream>
#include <algorithm>
int main() {
int arr[] = { 1, 2, 3, 4, 5 };
std::for_each(arr, arr + sizeof(arr) / sizeof(int), [](int x) {std::cout<<x<<" ";});
std::cout << std::endl;
}
Cách truyền các phần tử bên ngoài phạm vi vào bên trong các hàm lambda
Sử dụng [=]
[=](int &x) {
// Tất cả các phần tử bên ngoài đã được chuyển bằng tham trị
}
Sử dụng [&]
[&](int &x) {
// Tất cả các phần tử bên ngoài đã được chuyển bằng tham chiếu
}
Hãy xem ví dụ bên dưới, để thấy rõ ràng cách sử dụng các phần tử bên ngoài phạm vi vào bên trong các hàm lambda.
#include <iostream>
#include <algorithm>
int main() {
int arr[] = { 1, 2, 3, 4, 5 };
int mul = 5;
std::for_each(arr, arr + sizeof(arr) / sizeof(int), [&](int x) {
std::cout<<x<<" ";
// Có thể thay đổi giá trị của biến mul bên trong hàm lambda
// vì các phần tử bên ngoài đều có quyền ghi trong thân hàm này.
mul = 3;
});
std::cout << std::endl;
std::for_each(arr, arr + sizeof(arr) / sizeof(int), [=](int &x) {
x= x*mul;
// Không thể thay đổi giá trị của biến mul bên trong hàm lambda
// vì các phần tử bên ngoài có quyền chỉ đọc trong thân hàm này.
// mul = 9;
});
std::cout << std::endl;
std::for_each(arr, arr + sizeof(arr) / sizeof(int), [](int x) {
// Không thể truy xuất đến biến mul bên trong hàm lambda
// vì các phần tử bên ngoài không hiện hữu trong phạm vi thân hàm này.
//std::cout<<mul<<" ";
});
std::cout << std::endl;
}
Để lại một bình luận