0

std::function trong C++

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).

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí