functor 是重载了 operator() 的类,可像函数一样调用且带有状态;如 Adder(5)(10) 返回 15,它非函数指针也非 lambda,但支持内联优化与模板推导,适用于需携带不变数据的泛型场景。
operator() 的类在 C++ 里,functor 不是语言关键字,也不是标准库类型,而是一种惯用法:只要一个类定义了 operator() 成员函数,它就能像函数一样被调用。比如:
struct Adder {
int offset;
Adder(int o) : offset(o) {}
int operator()(int x) const { return x + offset; }
};
Adder add5(5);
int result = add5(10); // 等价于 add5.operator()(10),返回 15
关键点在于:它不是函数指针,也不是 lambda(虽然 lambda 编译后也生成 functor),而是有状态、可定制、能内联的类实例。你传的是对象,不是地址,所以编译器更容易优化。
当需要携带数据(如阈值、权重、缓存)且该数据在调用间保持不变时,functor 比捕获 lambda 更可控——尤其在泛型上下文中。比如 std::sort 接收比较器:
struct CaseInsensitiveCompare {
bool operator()(const std::string& a, const std::string& b) const {
return std::lexicographical_compare(
a.begin(), a.end(), b.begin(), b.end(),
[](char x, char y) { return std::tolower(x) < std::tolower(y); }
);
}
};
std::vector v = {"Zoo", "apple", "Banana"};
std::sort(v.begin(), v.end(), CaseInsensitiveCompare{});
这里不能直接用带捕获的 lambda(如 [&](...){...})传给模板函数,因为闭包类型无法显式写出;而无捕获 lambda 虽可退化为函数指针,但失去状态能力。functor 显式、可命名、可特化,适合复杂策略封装。
std::function 是类型擦除容器,能装任何可调用物(函数指针、lambda、functor),但带来间接调用开销(虚函数或函数指针跳转)和内存分配可能(小对象优化虽存在,但不保证)。functor 是具体类型,零成本抽象:
std::transform(..., MyFunctor{})),编译器可见全部实现,通常内联std::function 可以std::function 只暴露调用接口简单说:写算法库、STL 风格组件、性能敏感路径,优先用 functor;做

std::function。
常见错误集中在三个地方:
operator() 加 const:若 functor 被传给只接受 const 引用的算法(如 std::for_each 内部),非 const 版本无法匹配std::vector)时,未定义移动构造/赋值:STL 算法可能复制 functor 实例,若拷贝代价大又没禁用或优化,会拖慢性能decltype(f()) 辅助最隐蔽的问题是 functor 对象被算法多次复制却没意识到——比如在 std::transform 中每个元素都 new 一个内部缓存,结果创建了 N 份冗余状态。真正需要共享状态时,应通过指针或引用传递,而非依赖 functor 本身。