Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Functor (Function Object) trong C++

Functor (function object) là đối tượng của lớp có nạp chồng operator(), cho phép gọi như hàm: obj(args). Khác với function pointer, functor có thể mang trạng thái (state) và được inline tốt hơn bởi compiler.

Ví dụ cơ bản

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

struct Square {
    int operator()(int x) const { return x * x; } // functor
};

int main() {
    vector<int> v = {1,2,3,4,5};
    Square sq;
    transform(v.begin(), v.end(), v.begin(), sq); // dùng functor
    for (int x : v) cout << x << ' '; // 1 4 9 16 25
    return 0;
}

Functor có trạng thái (Stateful Functor)

struct Multiplier {
    int factor;
    Multiplier(int f) : factor(f) {}
    int operator()(int x) const { return x * factor; }
};

int main() {
    vector<int> v = {1,2,3};
    transform(v.begin(), v.end(), v.begin(), Multiplier(10));
    // v = {10, 20, 30}
}

Functor vs Function Pointer vs Lambda

Ví dụ STL: So sánh tùy chỉnh cho set/priority_queue

struct DescCompare {
    bool operator()(int a, int b) const { return a > b; } // min-heap cho priority_queue
};
priority_queue<int, vector<int>, DescCompare> minHeap;

// Hoặc lambda C++11
auto cmp = [](int a, int b) { return a > b; };
priority_queue<int, vector<int>, decltype(cmp)> minHeap(cmp);

std::function – Wrapper đa hình

Khi cần lưu trữ bất kỳ callable nào (function pointer, functor, lambda, bind):

#include <functional>
std::function<int(int)> f1 = Square();      // functor
std::function<int(int)> f2 = [](int x){ return x*x; }; // lambda
std::function<int(int)> f3 = [](int x){ return x*x; }; // function pointer
cout << f1(5) << f2(5) << f3(5); // 25 25 25

Lưu ý: std::function có overhead (type erasure, heap allocation cho callable lớn) – tránh dùng trong hot path.

C++20: Concepts & Callable

template<typename F>
concept UnaryPredicate = requires(F f, int x) { { f(x) } -> convertible_to<bool>; };

void process(UnaryPredicate auto pred) { ... } // chấp nhận functor, lambda, function ptr
Đặc điểmFunction PointerFunctorLambda (C++11)
Cú phápint (*f)(int)struct { R operator()(Args)... }[captures](params){body}
Trạng tháiKhông (global/static)Có (member variable)Có (capture)
Inline optimizationKhóDễ (type rõ ràng)Rất tốt
TypeChung cho cùng signatureMỗi struct = type riêngUnique closure type
STL algorithmsOKOK (thường nhanh hơn)OK (best)