1. Giới thiệu về std::function
std::function
là một template lớp trong C++ cho phép lưu trữ và gọi các đối tượng có thể gọi được (callable).
std::function
đặc biệt hữu ích khi cần truyền các callable như tham số hoặc lưu trữ chúng để gọi lại sau này.
2. Khai báo std::function
Cú pháp khai báo std::function
:
std::function<ReturnType(ArgTypes...)> name;
Trong đó:
- ReturnType: Kiểu dữ liệu trả về của Callable.
- ArgTypes...: Danh sách kiểu của các tham số mà Callable nhận.
- name: Tên biến std::function.
Ví dụ
#include <iostream>
#include <functional> int add(int a, int b) { return a + b; } int main() { std::function<int(int, int)> operation = add; std::cout << "Kết quả: " << operation(3, 5) << std::endl; return 0;
}
Output:
Kết quả: 8
3. std::function
với các loại Callable
3.1. Lưu trữ hàm thông thường
#include <iostream>
#include <functional> void hello() { std::cout << "Xin chào!\n"; } int main() { std::function<void()> func = hello; func(); return 0;
}
3.2. Lưu trữ lambda expression
std::function<int(int, int)> multiply = [](int a, int b) { return a * b; };
std::cout << multiply(3, 4); // Output: 12
3.3. Lưu trữ functor (đối tượng hàm)
struct Subtract { int operator()(int a, int b) { return a - b; }
}; std::function<int(int, int)> sub = Subtract();
std::cout << sub(10, 3); // Output: 7
3.4. Lưu trữ con trỏ thành viên
struct Example { int value; void print() { std::cout << "Giá trị: " << value << std::endl; }
}; Example obj{10};
std::function<void(Example&)> func = &Example::print;
func(obj); // Output: Giá trị: 10
4. Truyền std::function làm tham số
std::function
có thể được sử dụng để truyền hàm như tham số.
Ví dụ
void execute(std::function<int(int, int)> func, int a, int b) { std::cout << "Kết quả: " << func(a, b) << std::endl;
} int main() { execute([](int x, int y) { return x * y; }, 5, 6); return 0;
}
Output:
Kết quả: 30
5. Khi nào nên dùng std::function?
Nên dùng khi:
- Cần lưu trữ và gọi nhiều loại Callable khác nhau.
- Cần truyền Callable vào hàm mà không muốn dùng template.
- Cần thay đổi hành vi của chương trình bằng cách lưu trữ các hàm khác nhau.
Không nên dùng khi:
- Hiệu suất là ưu tiên hàng đầu (có thể sử dụng con trỏ hàm hoặc template thay thế).
- Callable không thay đổi (dùng con trỏ hàm trực tiếp sẽ nhanh hơn).