C++函数适配器

简介: 先弄清几个概念,什么叫一元函数,二元函数 1.    一元函数一个参数2. 二元函数 两个参数3. 一元谓词 一个参数,返回类型为bool型4. 二元谓词 两个参数,返回类型为bool型 函数适配器是用来让一个函数对象表现出另外一种类型的函数对象的特征。

先弄清几个概念,什么叫一元函数,二元函数

1.    一元函数一个参数
2. 
二元函数 两个参数
3. 一元谓词 一个参数,返回类型为bool型
4. 二元谓词 两个参数,返回类型为bool型

函数适配器是用来让一个函数对象表现出另外一种类型的函数对象的特征。因为,许多情况下,我们所持有的函数对象或普通函数的参数个数或是返回值类型并不是我们想要的,这时候就需要函数适配器来为我们的函数进行适配

 

C++中有三类适配器,分别是容器适配器,迭代器适配器和函数适配器,这里主要介绍函数适配器。
函数适配器用于特化和扩展一元二元函数对象,函数适配器主要有以下两类:
1 绑定器

该类适配器用于将二元函数适配成一元函数

 将二元函数的一个参数绑定到一个特定的值上,将二元函数对象转换成一元函数对象。
  绑定器适配器有两种:bind1st bind2nd。每个绑定器接受一个函数对象和一个值
  bind1st将给定值绑定到二元函数对象的第一个实参
  bind2nd将给定值绑定到二元函数对象的第二个实参
  例子:

先看下count_if的普通用法

count_if:  利用输入的函数,对标志范围内的元素进行比较操作,返回结果为true的个数。例如:vecInt是用vector<int>声明的容器,已包含1,3,5,7,9元素,现要求求出大于等于3的元素个数

 

bool GreaterThree(int iNum)
{
if(iNum>=3)
{
return true;
}
else
{
return false;
}
}
int iCount = count_if(vecIntA.begin(),vecIntA.end(), GreaterThree);
//这里要求GreaterThree的函数参数必须是一个
//此时iCount == 4

 count_if(vec.begin(), vec.end(), bind2nd(less_equal<int>(), 10)); 
// less_equal<int>()函数是两个参数,怎样让他变成一个参数呢?
less_equal是STL为我们提供的一个函数对象,它有两个参数,其作用是比较第一个参数值是否<=第二个参数值。但是count_if要求我们第三个参数必须是一个一元谓词(就是只有一个参数),所以我们用bind2nd对该函数对象进行适配,将10绑定到该函数对象的第二个参数上。
(意思就是说less_equal<int>( _Left, _Right)这个函数只要他的第二个参数,第一个参数忽略)
现在cont_if执行的功能实际上就变成了查找给定序列中值<=10的元素的个数

 

取反器 将函数对象的结果真值求反
  
取反器有两种:not1not2
  not1
是对一元函数对象求反的取反器,传递给函数对象的只有一个参数,则要使用这个not1
  not2
是对二元函数对象求反的取反器
  
例子
 int* where=find_if(&array[0],&array[100],not1(bind2nd(breater<int>(),200)))

推荐一个很好的判断传参的方法:先写一个类,重载()算符,并接受传递进来的参数,判断后再返回真假
例子:

#include <functional>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cassert>
#define ASSERT assert
using namespace std;
class Rand:public binary_function<int, int, int>
{
public:
    Rand()
    { srand((unsigned int)time(NULL)); }
    int operator()(int minval, int maxval) const
    {
        ASSERT(maxval>minval);
        ASSERT(minval>=0);
        ASSERT(maxval<=RAND_MAX);
        return (rand()%(maxval-minval)) + minval;
    }
};
int main()
{
    cout<<Rand()(1,5)<<endl; //[1,5)
    cout<<bind1st(Rand(),20)(30)<<endl;
    return 0;
}

 

 

相关文章
|
7月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
206 0
|
10月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
569 6
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
575 6
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
153 3
|
安全 编译器 C++
【C++篇】C++类与对象深度解析(三):类的默认成员函数详解
【C++篇】C++类与对象深度解析(三):类的默认成员函数详解
137 3
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
340 0
C++ 多线程之线程管理函数
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
2675 1
|
存储 编译器 C++
C++入门3——类与对象2-1(类的6个默认成员函数)
C++入门3——类与对象2-1(类的6个默认成员函数)
216 1
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
237 0
C++入门6——模板(泛型编程、函数模板、类模板)