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 是统一调用各种可调用对象的标准方式。