0Pricing
C++ Academy · 课时

函数对象与仿函数

编写重载 operator() 的类,创建带状态的可调用对象

函数对象与仿函数 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。

什么是函子?

函子(函数对象)是重载了 operator() 的类。实例可以像函数一样被调用。

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

Square sq;
std::cout << sq(5);   // 25

为什么不直接使用函数?

函子携带状态,而普通函数不携带。状态可以实现配置、计数以及有状态的回调。

struct Counter {
    int count = 0;
    int operator()(int x) { ++count; return x; }
};

Counter c;
c(10); c(20); c(30);
std::cout << c.count;   // 3

可配置的行为

将配置存储在函子的成员中。同一种函子类型可以适用于多组参数。

struct GreaterThan {
    int threshold;
    bool operator()(int x) const { return x > threshold; }
};

GreaterThan over10{10};
over10(15);    // true
over10(5);     // false

将函子与 STL 算法结合使用

STL 算法接受任何可调用对象——函子、Lambda 表达式和函数指针。

std::vector<int> v = {1, 11, 5, 99, 8};
auto it = std::find_if(v.begin(), v.end(), GreaterThan{10});
std::cout << *it;   // 11

<functional>中的预定义函子

标准库提供了现成的函子:std::plus、std::less、std::equal_to、std::negate 等。

#include <functional>
std::vector<int> v = {3, 1, 4, 1, 5};
std::sort(v.begin(), v.end(), std::greater<int>{});
// sorted descending

函子与函数指针

函子通常更容易内联,因为它们的 operator() 是直接调用。函数指针可能更加灵活,但属于间接调用。

将函子作为模板参数

许多 STL 容器和算法都接受函子作为模板参数,例如集合比较器、哈希函数和分配器。

std::set<int, std::greater<int>> s = {1, 2, 3};
// s iterates in descending order: 3, 2, 1

Lambda 表达式就是函子

编译器会为每个 Lambda 表达式生成一个带有 operator() 的唯一类。Lambda 表达式是函子的语法糖。

何时编写函子

在以下情况下,请使用手写函子:

  • 同一逻辑会在多处使用(为它命名)
  • 它是公共 API 的一部分
  • 它需要具备特定行为的复制构造或移动构造能力

何时改用 Lambda 表达式

对于一次性使用的场景,Lambda 表达式更简短、更清晰。对于可复用的行为,命名函子可以提高可读性。

可组合性

您可以使用 std::bind 组合函子,或者采用更现代的方式组合 Lambda 表达式。Boost 等函数式库也提供组合器。

快速检查

与普通函数相比,函子的主要能力是什么?

总结

函子是带有 operator() 的类。它可以携带状态、与 STL 算法集成,并构成 Lambda 表达式的基础。可复用的行为应使用命名函子,一次性逻辑则适合使用 Lambda 表达式。

常见问题解答

「函数对象与仿函数」课时是免费的吗?

是的 — 「函数对象与仿函数」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。

「函数对象与仿函数」这节课中我会学到什么?

编写重载 operator() 的类,创建带状态的可调用对象 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C++ Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「函数对象与仿函数」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C++ Academy 课中编写并运行代码吗?

能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 函数对象与仿函数
  2. Lambda 按值、按引用捕获与 mutable
  3. 泛型 Lambda 与闭包(C++14)
  4. std::function:类型擦除的可调用对象
← 返回 C++ Academy