详解C++函数对象和谓词


前言:在自然语言的世界里,无论是汉语还是英语,都有 “谓词”(谓语)的概念,像汉语里的 “是”,英语中的 “is”,它们在句子中承担着表达动作、状态等关键语义的重要角色。那在计算机语言的领域中,是否也存在谓词呢?答案是肯定的!
计算机语言里的谓词和函数、函数对象紧密相连。函数对大家来说或许并不陌生,不过函数对象,可能就有很多人不太了解了。接下来,我们就把关注点聚焦在函数对象上,深入探究它的奥秘。


概念

函数对象本质上是一个类或者结构体,不过它具备特殊能力,即对函数调用运算符 () 进行了重载。这一重载操作让这个类或结构体的对象在使用时,表现得和普通函数一样,可以像调用函数那样去调用这个对象

表现
当你创建一个对 () 运算符重载的类或结构体后,就能创建该类或结构体的对象。之后,你可以像调用普通函数一样,使用 对象名(参数列表) 的形式来调用这个对象,因为重载的 () 运算符会处理传入的参数并执行相应操作。

#include <iostream>

// 定义一个函数对象类
class Adder {
public:
    // 重载函数调用运算符 ()
    int operator()(int a, int b) {
        return a + b;
    }
};

int main() {
    // 创建函数对象实例
    Adder adder;
    // 像调用函数一样调用函数对象
    int result = adder(3, 5);
    std::cout << "3 + 5 的结果是: " << result << std::endl;
    return 0;
}

函数对象里的谓词

  • 谓词定义 :谓词是一种返回布尔值(true 或 false)的函数对象。其主要作用是进行条件判断,就像裁判根据特定规则判断某个情况是否成立一样,在程序里用于评估给定的参数是否满足特定条件。
  • 一元谓词:一元谓词只接受一个参数,对这个参数进行判断并返回布尔值。例如用于判断一个数是否为偶数的谓词就是一元谓词。
  • 二元谓词 二元谓词接受两个参数,根据这两个参数之间的关系进行判断并返回布尔值。在排序算法中常用二元谓词来指定元素的排序规则。
一元谓词操作
#include <iostream>
#include <vector>
#include <algorithm>

// 一元谓词:判断一个数是否为偶数
struct IsEven {
    bool operator()(int num) const {
        return num % 2 == 0;
    }
};

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6};
    // 使用 std::find_if 结合一元谓词查找第一个偶数
    auto it = std::find_if(numbers.begin(), numbers.end(), IsEven());
    if (it != numbers.end()) {
        std::cout << "第一个偶数是: " << *it << std::endl;
    } else {
        std::cout << "未找到偶数。" << std::endl;
    }
    return 0;
}

在这个示例中,IsEven 是一个一元谓词函数对象,它接受一个整数参数,判断该数是否为偶数并返回相应的布尔值。std::find_if 算法使用这个谓词在 numbers 容器中查找第一个偶数

二元谓词示例
#include <iostream>
#include <vector>
#include <algorithm>

// 二元谓词:降序排序
struct Greater {
    bool operator()(int a, int b) const {
        return a > b;
    }
};

int main() {
    std::vector<int> numbers = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
    // 使用 std::sort 结合二元谓词进行降序排序
    std::sort(numbers.begin(), numbers.end(), Greater());
    std::cout << "降序排序后的结果: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}

在这个示例中,Greater 是一个二元谓词函数对象,它接受两个整数参数,比较它们的大小并返回 a > b 的结果。std::sort 算法使用这个谓词对 numbers 容器中的元素进行降序排序

内建函数对象

概念 :C++STL中内建了一些函数对象,也就是说别人已经给你写好了一些函数对象,你直接拿去用就行了
分类

  • 算术仿函数
  • 关系仿函数
  • 逻辑仿函数(不常用)
算术仿函数
  • template<class T> T plus<T> 加法仿函数
  • template<class T> T minus<T> 减法仿函数
  • template<class T> T multiplies<T> 乘法仿函数
  • template<class T> T divides<T> 除法仿函数
  • template<class T> T modulus<T> 取模仿函数
  • template<class T> T negate<T> 取反仿函数
#include<iostream>
#include<functional>
using namespace std;
int main()
{
	plus<int> p;
	cout << "加法仿函数运算结果:" << p(123, 456) << endl;

	modulus<int> md;
	cout << "取模仿函数运算结果:" << md(35, 14) << endl;

	negate<int> n;//一元运算,下面只传一个参数
	cout << "取反仿函数运算结果:" << n(10) << endl;
}
关系仿函数
  • template<class T> bool equal_to<T> 等于

  • template<class T> bool not_equal_to<T> 不等于

  • template<class T> bool greater<T> 大于

  • template<class T> bool greater_equal<T> 大于等于

  • template<class T> bool less<T> 小于

  • template<class T> bool less_equal<T> 小于等于

使用:

#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
int main()
{
	int arr[10] = { 5,9,0,7,6,4,8,3,1,2 };
	//降序排序
	sort(arr, arr + 10, greater<int>());
	for (int i = 0; i < 10; ++i) {
		cout << arr[i] << " ";
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值