【C++】STL 算法 ④ ( 函数对象与谓词 | 一元函数对象 | “ 谓词 “ 概念 | 一元谓词 | find_if 查找算法 | 一元谓词示例 )

2024-01-07 08:57:07 浏览数 (1)

文章目录
  • 一、函数对象与谓词
    • 1、一元函数对象
    • 2、" 谓词 " 概念
    • 3、find_if 查找算法
  • 二、一元谓词示例
    • 1、代码示例 - 一元谓词示例
    • 2、执行结果

一、函数对象与谓词


1、一元函数对象

" 函数对象 " 是通过 重载 函数调用操作符 () 实现的 operator() , 函数对象 可以 像普通函数一样被调用 , 但同时它们 还可以拥有状态并且可以有多个成员函数 ;

" 一元函数对象 " 是 函数对象 的一种 , 只 接受一个参数 并返回某个结果的 函数对象 称为 " 一元函数对象 " ;

" 一元函数对象 " 在 标准模板库 ( STL , Standard Template Library ) 中特别常见 , 尤其是在 STL 算法中 , 因为它们可以用作自定义操作 , 以适应各种不同的需求 ; 例如 : 使用 一元函数对象 来定义一个操作 , 该操作将被应用于容器中的每个元素 ;

在上一篇博客 【C 】STL 算法 ③ ( 函数对象中存储状态 | 函数对象作为参数传递时值传递问题 | for_each 算法的 函数对象 参数是值传递 ) 中的代码示例中的 PrintT 函数对象 , 其 重载的 函数调用操作符 函数 void operator()(T& t) 只接收一个参数 , 这是一个 一元函数对象 ;

代码语言:javascript复制
//函数对象 类重载了()
template <typename T>
class PrintT {
public:
	void operator()(T& t) {
		cout << n << " . " << t << endl;
		// 每调用一次, 自增 1
		n  ;
	}

private:
	// 每调用一次, 该成员自增 1
	// 该状态一直存储
	int n = 0;
};

2、" 谓词 " 概念

" 谓词 ( Predicate ) " 是 C 语言中的 标准模板库 ( STL , Standard Template Library ) 算法的 重要概念 ;

" 谓词 ( Predicate ) " 是一个 返回 布尔 bool 类型值 的 函数对象 / 仿函数 或 Lambda 表达式 / 普通函数 , 可用于对某个条件进行检查 ;

当 " 谓词 ( Predicate ) " 被用于算法中时 , 会对序列中的元素进行某种测试 , 返回一个布尔类型的测试结果 , 根据不同的结果执行不同的操作 ;

" 谓词 ( Predicate ) " 类型 :

  • 普通函数
  • 函数指针
  • 重载了 函数调用操作符 的 函数对象 / 仿函数 , 有 operator() 函数 ;

" 谓词 ( Predicate ) " 通常被设计成可以接受一定数量的参数

  • 一元谓词 : 接受一个参数
  • 二元谓词 : 接受两个参数

谓词的 函数体 中 根据 传入的 参数 进行计算 , 并返回 true 或 false 布尔值 ;

3、find_if 查找算法

std::find_if 算法 是 C 语言的 标准模板库 中提供的一种算法 , 该算法 用于 在 容器 中查找满足特定条件的第一个元素 ;

find_if 算法 的原理是 : 执行该算法时 , 遍历容器序列 , 对每个元素应用指定的 一元谓词 ;

  • 如果 找到满足 一元谓词 返回 true 的元素 , 则返回 指向该元素的迭代器 ;
  • 如果 没有找到满足 一元谓词 返回 true 的元素 , 则返回 结束迭代器 ;

std::find_if 算法的函数原型如下 :

代码语言:javascript复制
// FUNCTION TEMPLATE find_if
template <class _InIt, class _Pr>
_NODISCARD _InIt find_if(_InIt _First, const _InIt _Last, _Pr _Pred) { // find first satisfying _Pred
    _Adl_verify_range(_First, _Last);
    auto _UFirst      = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    for (; _UFirst != _ULast;   _UFirst) {
        if (_Pred(*_UFirst)) {
            break;
        }
    }

    _Seek_wrapped(_First, _UFirst);
    return _First;
}

二、一元谓词示例


下面的代码示例中 , 定义了 一元谓词 :

代码语言:javascript复制
template <typename T>
class equalFour {
public:
	bool operator()(T& t) {
		if (t == 4) {
			return true;
		}
		else {
			return false;
		}
	}
};

该 一元谓词 的 作用是 , 接收一个 T 类型的元素 , 判断该元素的值是否为 4 , 如果是 , 则返回 true , 如果不是 , 则返回 false ;

将该 一元谓词 , 传入到 find_if 算法函数中 ;

执行该算法时 , 遍历容器序列 , 对每个元素应用指定的 一元谓词 , 这里会查找满足 值等于 4 的元素 ;

  • 如果找到满足 一元谓词 返回 true 的元素 , 则返回 指向该元素的迭代器 ;
  • 如果没有找到满足 一元谓词 返回 true 的元素 , 则返回 结束迭代器 ;

1、代码示例 - 一元谓词示例

代码语言:javascript复制
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

//函数对象 类重载了()
template <typename T>
class equalFour {
public:
	bool operator()(T& t) {
		if (t == 4) {
			return true;
		}
		else {
			return false;
		}
	}
};

int main() {

	// 创建一个 vector 单端数组容器
	vector<int> vec;

	// 向容器中插入元素
	vec.push_back(1);
	vec.push_back(2);
	vec.push_back(3);
	vec.push_back(4);
	vec.push_back(5);

	// 查找等于 4 的元素
	auto it = find_if(vec.begin(), vec.end(), equalFour<int>());

	if (it != vec.end())
	{
		cout << "找到了第一个等于 4 的数 : " << *it << endl;
	}


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
};

2、执行结果

执行结果 :

找到了第一个等于 4 的数 : 4 请按任意键继续. . .

0 人点赞