C++ std::not_fn 函数

2025年3月21日 | 阅读 4 分钟

C++ 中的 std::not_fn 实用程序是 C++ 头文件的一个组成部分,并在 C++17 中引入。通过生成否定其他可调用对象(例如函数、函数 指针lambda 表达式 或函数 对象)结果的 函数 对象,它在函数式编程中发挥着非常专业和实用的作用。

我们经常在函数式编程和算法上下文中处理谓词,这些函数依赖于条件并返回 布尔 结果(真或假)。有时,我们可能希望自动反转(否定)现有函数的逻辑,而不是创建新的谓词来检查相反的条件。这就是 std::not_fn 发挥作用的地方。

为什么使用 std::not_fn?

std::not_fn 的主要目的是接受一个现有的可调用对象(函数、lambda 表达式或函数对象),并返回一个新的可调用对象,该对象会否定原始可调用对象的结果。这在需要现有谓词的相反条件的算法中特别有用,例如 std::find_if、std::remove_if 或 std::all_of。通过使用 std::not_fn,您可以轻松反转谓词的逻辑,而无需编写额外的代码来手动否定其结果。

语法

它具有以下语法:

参数

  • Fn:它是一个可调用对象,其结果将被否定,例如函数、函数指针、lambda 表达式或函数对象。

返回值

一个可调用对象(函数对象),当被调用时,返回原始函数结果的否定。

程序

我们来看一个例子来说明 C++ 中的 std::not_fn 函数。

输出

 
Odd numbers (negation of is_even): -1 25 7 
Non-positive numbers (negation of IsPositive functor): -1 -8 0 
Numbers <= 5 (negation of lambda is_greater_than_five): -1 -8 0 
Any negative numbers? Yes   

说明

此代码演示了将 {std::not_fn} 与函数、函数对象和 lambda 表达式一起使用。由于它否定了可调用对象的结果,因此当我们希望反转条件而无需编写新逻辑时,'std::not_fn' 函数非常有用。

  1. 函数:要确定一个数字是否为偶数,请使用 'is_even' 函数。为了检查 奇数,我们反转此推理并使用 {std::not_fn(is_even)}。{std::for_each} 循环打印奇数,因为它遍历向量。
  2. 函数对象:要确定一个整数是否为正数,请使用 {IsPositive} 函数对象。通过应用 {std::not_fn(IsPositive())},我们获得一个识别非正值的可调用对象,并报告结果。
  3. Lambda 表达式:一个 lambda 表达式确定给定值是否大于 5。使用此 lambda 表达式,我们使用 {std::not_fn} 来打印小于或等于 5 的值。
  4. 算法:最后,通过否定 IsPositive 函数对象,std::any_of 确定向量是否包含任何负值。

复杂度分析

时间复杂度

std::for_each 循环的每次迭代都遍历向量中的每个元素。由于函数调用和 std::not_fn 应用程序在每次迭代中都是常数时间操作,因此每个循环的时间复杂度为 O(n),其中 n 是向量中的条目数。

不利的一面是,std::any_of 在最坏情况下的时间复杂度为 O(n)O(n)O(n),因为它遍历整个范围(或向量)以根据指定的谓词检查每个元素。如果没有元素满足条件,算法必须评估所有元素,导致线性时间复杂度。

空间复杂度

除了迭代器和临时 变量 之外,所有操作的空间复杂度都为 O(1)O(1)O(1),无论输入大小如何,它们都需要常量内存。这是因为向量本身的大小在操作期间不会改变,从而导致算法执行的内存使用量固定。