Skip to content

函数对象

函数对象是实现了调用运算符 operator() 的对象。它既能像函数一样调用,也能用成员保存策略或运行时状态。

定义与使用

cpp
struct DivisibleBy {
    int divisor;

    bool operator()(int value) const {
        return value % divisor == 0;
    }
};

std::vector<int> values{1, 2, 3, 4, 5, 6};
auto count = std::ranges::count_if(values, DivisibleBy{3});

算法通常按值接收谓词,因此内部可能复制函数对象。谓词不应依赖“整个算法过程中只有唯一副本”这一假设。

remove_if 的要求

cpp
values.erase(
    std::remove_if(values.begin(), values.end(),
                   [](int value) { return value % 3 == 0; }),
    values.end());

谓词应根据元素值稳定地给出结果。用内部计数器删除“第 n 个元素”会依赖算法调用次数与复制行为,属于脆弱设计。若需求与位置有关,应显式遍历或先计算目标迭代器。

cpp
if (values.size() >= 3) {
    values.erase(values.begin() + 2);
}

Lambda 与状态

cpp
int threshold = 10;
auto greater = [threshold](int value) { return value > threshold; };

Lambda 本质上也是编译器生成的函数对象。按值捕获提供独立状态,按引用捕获要求被引用对象在调用期间持续存活。

TIP

需要跨调用共享可变状态时,先确认算法是否允许有副作用。很多排序、删除和并行算法要求谓词满足更严格的稳定性与线程安全条件。

SIGNAL MAINTAINED · BUILT FROM MARKDOWN