仿函数(Functor)是什么?

chenchen / 2024-09-25 / 原文

仿函数(Functor)

仿函数是通过重载()运算符类或结构体的对象。这样一个对象可以像普通函数一样被调用。

仿函数通常用于需要在对象内部保留状态或多次调用时有特定行为的情况。

特点:

  1. 仿函数是一个类对象。
  2. 通过重载 () 运算符使得类对象像函数一样可以被调用。
  3. 可以在类中保留状态或成员变量,提供比普通函数更复杂的逻辑和功能。
  4. 适合在需要复用逻辑和状态的场景中使用。

示例:

#include <iostream>
using namespace std;

class Adder {
public:
    Adder(int x) : value(x) {}

    // 重载 () 操作符,使对象能像函数一样调用
    int operator()(int y) {
        return value + y;
    }

private:
    int value;
};

int main() {
    Adder add5(5);  // 创建一个仿函数对象,初始值为5
    cout << add5(10) << endl;  // 输出 15
    return 0;
}

Lambda 表达式

Lambda 表达式是一种匿名函数,可以在函数内定义一个临时的、无名的函数。

Lambda 表达式非常适合在简单的函数逻辑下使用,不需要事先定义一个函数名称。

它主要用于简化代码、捕获上下文环境中的变量、以及函数式编程等场景。

特点:

  1. Lambda 表达式是一个匿名函数,直接在使用的地方定义。
  2. 语法简洁,适合用于临时、一次性的小函数。
  3. 可以捕获外部作用域中的变量,提供便捷的上下文共享能力。
  4. 一般用于简单的逻辑处理,不需要复杂的状态保存。

Lambda 表达式的语法:

[capture](parameters) -> return_type {
    // function body
};

示例:

#include <iostream>
using namespace std;

int main() {
    int x = 10;
    auto add = [x](int y) {
        return x + y;  // 捕获外部变量x
    };
    
    cout << add(5) << endl;  // 输出 15
    return 0;
}

仿函数与 Lambda 的区别

  1. 定义形式

    • 仿函数是通过类重载 () 运算符实现的。
    • Lambda 表达式是匿名函数,直接在使用时定义。
  2. 状态管理

    • 仿函数类可以通过成员变量保存状态,适合需要在多次调用间保持状态的场景。
    • Lambda 表达式可以通过捕获外部变量来实现类似的效果,但一般不会像仿函数那样专门用于状态管理。
  3. 灵活性

    • 仿函数可以通过类的复杂逻辑实现更灵活的功能。
    • Lambda 表达式适合实现简单的逻辑,更加简洁明了。
  4. 适用场景

    • 仿函数更适合用于复杂的、需要状态维护的场景。
    • Lambda 表达式适用于临时、轻量级的函数逻辑。