CPP STL学习一: 「一元谓词」、「函数对象和函数指针」

前记

template <class InputIter, class UnaryPredicate>
bool all_of(InputIter first, InputIter last, UnaryPredicate unary_pred) {
    while (first != last) {
        if (!unary_pred(*first++)) {
            return false;
        }
    }
    return true;
}


在学习这个STL基本算法 all_of 时,没看懂unary_pred 的语法。

理解 STL 算法 all_of 中的一元谓词 unary_pred

在 C++ STL 算法中,all_of 是一个常用的算法,用于检查指定范围内的所有元素是否满足某个条件。其核心在于理解一元谓词 unary_pred 的语法和作用。

unary_pred(*first) 的解析
  1. *first:解引用迭代器 first,获取当前迭代器指向的元素值。
  2. unary_pred:是一个一元谓词,可以是函数指针、函数对象、Lambda 表达式或普通函数。它接受一个参数(当前元素)并返回布尔值,表示该元素是否满足条件。

一元谓词的四种形式

1. 普通函数

普通函数是最简单的形式,接受一个参数并返回布尔值。

bool is_even(int x) {
    return x % 2 == 0;
}

2. Lambda 表达式

Lambda 表达式是 C++11 引入的匿名函数,常用于简化代码。

auto is_even = [](int x) { return x % 2 == 0; };

3. 函数指针

函数指针指向一个普通函数,适合固定逻辑的场景。

bool (*predicate)(int) = is_even;

4. 函数对象(仿函数)

函数对象是一个类或结构体,重载了 operator(),可以保存状态。

struct IsEven {
    bool operator()(int x) const {
        return x % 2 == 0;
    }
};
IsEven is_even_obj; // 实例化对象

lambda表达式和普通函数用的比较多,比较好理解,对于函数指针和函数对象这里需要补充讲一下。


函数对象 vs 函数指针的区别

特性函数指针函数对象(仿函数)
类型指向普通函数的指针类或结构体,重载 operator()
保存状态不支持支持(通过成员变量)
灵活性较低,仅能指向固定函数高,可扩展行为或配置
使用方式直接调用函数调用对象的 operator()
内存开销较小(指针大小)可能较大(含成员变量)

 函数对象的优势:支持状态管理

函数对象的核心优势是能够保存状态,适用于需要动态配置的场景。例如,实现可定制的排序规则:

#include <vector>
#include <algorithm>

struct Compare {
    bool reverse;
    Compare(bool rev = false) : reverse(rev) {}

    bool operator()(int a, int b) const {
        return reverse ? (a > b) : (a < b);
    }
};

int main() {
    std::vector<int> v = {4, 2, 5, 1, 3};

    // 正序排序
    std::sort(v.begin(), v.end(), Compare());
    // 输出:1 2 3 4 5

    // 倒序排序
    std::sort(v.begin(), v.end(), Compare(true));
    // 输出:5 4 3 2 1
}


总结

  • 普通函数/Lambda:适合简单逻辑,代码简洁。
  • 函数指针:适合固定函数调用,无状态需求。
  • 函数对象:适合需要保存状态或动态配置的场景,灵活性更高。

在实际开发中,Lambda 表达式和函数对象使用频率较高,而函数指针多见于兼容旧代码或特定设计模式。根据需求选择合适的形式,能让代码更清晰、高效。

参考:

1.https://blog.csdn.net/bandaoyu/article/details/106358830

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值