Skip to content

functional — 函数对象

<functional> 提供函数对象、函数包装器、绑定器,是 C++ 函数式编程的基础设施。

std::function

cpp
#include <functional>

// 存储任意可调用对象(有类型擦除开销)
std::function<int(int, int)> add = [](int a, int b) { return a + b; };
std::function<void(const std::string&)> print = [](const std::string& s) {
    std::cout << s << "\n";
};

// 存储普通函数
int multiply(int a, int b) { return a * b; }
std::function<int(int, int)> mul = multiply;

// 存储成员函数
struct Foo {
    int value = 42;
    int get() const { return value; }
};
std::function<int(const Foo&)> getter = &Foo::get;
Foo foo;
std::cout << getter(foo) << "\n";  // 42

// 回调注册
class Button {
    std::function<void()> on_click_;
public:
    void set_click(std::function<void()> cb) { on_click_ = std::move(cb); }
    void click() { if (on_click_) on_click_(); }
};

std::bind

cpp
#include <functional>

int add(int a, int b, int c) { return a + b + c; }

// 绑定部分参数
auto add5 = std::bind(add, 5, std::placeholders::_1, std::placeholders::_2);
std::cout << add5(3, 2) << "\n";  // 10

// 重排参数
auto reordered = std::bind(add, std::placeholders::_2, std::placeholders::_1, 0);
std::cout << reordered(1, 2) << "\n";  // 3

// 绑定成员函数
struct Counter {
    int count = 0;
    void increment(int n) { count += n; }
};

Counter c;
auto inc = std::bind(&Counter::increment, &c, std::placeholders::_1);
inc(5);
std::cout << c.count << "\n";  // 5

// 现代替代:lambda(更清晰)
auto add5_lambda = [](int b, int c) { return add(5, b, c); };

标准函数对象

cpp
#include <functional>

// 算术
std::plus<int>{}(3, 4);       // 7
std::minus<int>{}(10, 3);     // 7
std::multiplies<int>{}(3, 4); // 12
std::divides<int>{}(10, 2);   // 5
std::modulus<int>{}(10, 3);   // 1
std::negate<int>{}(5);        // -5

// 比较
std::equal_to<int>{}(3, 3);       // true
std::not_equal_to<int>{}(3, 4);   // true
std::less<int>{}(3, 4);           // true
std::greater<int>{}(4, 3);        // true
std::less_equal<int>{}(3, 3);     // true
std::greater_equal<int>{}(4, 3);  // true

// 逻辑
std::logical_and<bool>{}(true, false);  // false
std::logical_or<bool>{}(true, false);   // true
std::logical_not<bool>{}(true);         // false

// 在算法中使用
std::vector<int> v = {5, 3, 1, 4, 2};
std::sort(v.begin(), v.end(), std::greater<int>{});  // 降序
std::sort(v.begin(), v.end(), std::less<>{});        // C++14 透明比较器

// priority_queue 最小堆
std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;

std::invoke

cpp
#include <functional>

// 统一调用任何可调用对象
int add(int a, int b) { return a + b; }
struct Foo { int val; int get() const { return val; } };

std::invoke(add, 3, 4);                    // 普通函数
std::invoke([](int x){ return x*2; }, 5); // lambda
Foo foo{42};
std::invoke(&Foo::get, foo);               // 成员函数
std::invoke(&Foo::val, foo);               // 成员变量

// 在模板中统一处理各种可调用对象
template<typename F, typename... Args>
auto call(F&& f, Args&&... args) {
    return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
}

std::reference_wrapper

cpp
#include <functional>

// 在容器中存储引用
int a = 1, b = 2, c = 3;
std::vector<std::reference_wrapper<int>> refs = {a, b, c};

for (auto& ref : refs) ref.get() *= 2;
std::cout << a << " " << b << " " << c << "\n";  // 2 4 6

// std::ref / std::cref
auto ref_a = std::ref(a);    // reference_wrapper<int>
auto cref_a = std::cref(a);  // reference_wrapper<const int>

// 在 std::bind 中传引用
void modify(int& x) { x *= 2; }
int val = 5;
auto f = std::bind(modify, std::ref(val));  // 传引用,不是拷贝
f();
std::cout << val << "\n";  // 10

关键认知

std::function 有类型擦除开销(虚函数调用 + 可能的堆分配),热路径用模板参数或 auto 保留具体类型。std::bind 在现代 C++ 中基本被 lambda 取代,更清晰。std::invoke 是统一调用各种可调用对象的标准方式。

系统学习 C++ 生态,深入底层架构