C++11系列学习之可调用对象包装器和绑定器

 更新时间:2022年04月25日 10:06:07   作者:小杰编程  
这篇文章主要介绍了C++11系列学习之可调用对象包装器和绑定器,下文基于C++的相关资料展开详细内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

旧标准的缺陷

学习新标准的语法之前,先来聊聊旧标准存在的缺陷,这样就可以理解为什么要在C++11中存在std::funtionstd::bind了,这就是所谓——知其然,并知其所以然

繁杂的调用对象

C++中可以调用的对象有很多,包括但不限于以下:

  • 函数指针
  • 仿函数(重载了"( )" 运算符)
  • 可被转换为函数指针的类对象
  • 类成员函数

问题浮出水面

这些调用对象在使用的时候具有比较统一的时候,但是定义的方式却是五花八门。因此,C++11中为了改善这个问题,提供了std::functionstd::bind来解决

std::function

std::function是可调用对象的包装器本质上是一个类模板可容纳除了类成员(函数)指针之外的所有可调用对象

小试牛刀

#include<iostream>
#include<functional>
class A
{
std::function<void()> callback_;
public:
A(const std::function<void()>& f) : callback_(f){}
void notify(void){
callback_(); //调用这个回调对象
}
};
class Foo{
public:
void operator()(void){
std::cout << __FUNCTION__ << std::endl;
}
};
int main(void)
{
Foo foo;
A aa(foo);
aa.notify(); //调用这个回调
return 0;
}
//输出
//operator()

std::function因为有着保存函数并可以延迟执行的特性,因此非常适合作为回调函数来使用

std::bind

std::bind用来将可调用对象与其参数一起进行绑定,绑定后的结果可以使用std::function进行保存,并延迟调用

作用

  • 将可调用对象与其参数一起绑定成一个仿函数
  • 将N元可调用对象转换成一元或N-1元可调用对象,即只绑定部分参数

占位符

std::bind可以将函数及其参数进行绑定,那么参数的位置与传入的位置相关,因此有了占位符的概念,例如std::placeholders::_1是第一个参数的占位符,当函数传入第一个参数的时候,就会把其进行替换,同理std::palceholders::_2是第二个占位符。

#include<iostream>
#include<functional>
void output(int x, int y){
std::cout << x << " " << y << std::endl;
}
int main(){
std::bind(output, 1, 2)(); //输出:1 2
std::bind(output, std::placeholders::_1)(1); //输出:1
std::bind(output, 2, std::placeholders::_2)(1,2); //输出:2 2
std::bind(output, std::placeholders::_2, std::placeholders::_1)(1, 2); //输出:2 1
}

高级用法

可以使用std::bind进行多个函数的组合,例如找出集合中大于5小于10的元素个数:

#include<iostream>
#include<functional>
using std::placeholders::_1;
auto f = std::bind(std::logical_and<bool>(), std::bind(std::greater<int>(), _1, 5),std::bind(std::less_equal<int>(), _1, 10)); //将两个函数参数绑定并进行组合
int count = std::count_if(coll.begin(), coll.end(), f); //使用

配合使用

std::bindstd::function配合使用非常的强大

#include<iostream>
#include<funcational>
class A{
public:
int i_ = 0;
void output(int x, int y){
std:cout << x << " " << y << std::endl;
}
};
int main(void){
A a;
std::function<void(int, int)> fr = std::bind(&A::output, &a, std::placeholders::_1,std::palceholders::_2); //注意
fr(1, 2); //输出:1 2
std::function<int&(void)> fr_i = std::bind(&A::i, &a);
fr_i() = 123;
std::cout << a.i_ << std::endl; //输出:123
}

可以看到上面std::bind在绑定类的成员函数的时候,需要把&a也传进去,这是因为成员函数编译器在使用的时候会自动传入一个this指针,所以我们绑定的时候需要额外传一个对象的地址

到此这篇关于C++11系列学习之可调用对象包装器和绑定器的文章就介绍到这了,更多相关C++11包装器和绑定器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言实现经典扫雷小游戏完整代码(递归展开 + 选择标记)

    C语言实现经典扫雷小游戏完整代码(递归展开 + 选择标记)

    这篇文章主要介绍了C语言小项目之扫雷游戏带递归展开 + 选择标记效果,本代码中,我们用字符 ! 来标识雷,文中附有完整代码,需要的朋友可以参考下
    2022-05-05
  • C语言中共用体和枚举的实现

    C语言中共用体和枚举的实现

    本文主要介绍了C语言中共用体和枚举的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-12-12
  • VSCode远程开发调试服务器c/c++代码

    VSCode远程开发调试服务器c/c++代码

    语音相关的好多项目要在linux上跑,但代码开发大多是在PC机上,本篇简单介绍一下怎么在个人电脑上用VSCode远程开发调试服务器上的c/c++代码。感兴趣的朋友跟随小编一起看看吧
    2020-04-04
  • C#中 MessageBox的使用技巧

    C#中 MessageBox的使用技巧

    这篇文章主要介绍了C#中 MessageBox的使用技巧,在C#中MessageBox消息对话框位于System.Windows.Forms命名空间中,更多详细的内容需要的朋友可以参考一下
    2022-08-08
  • 深入解析C++ STL中的常用容器

    深入解析C++ STL中的常用容器

    这里我们不涉及容器的基本操作之类,只是要讨论一下各个容器其各自的特点。STL中的常用容器包括:顺序性容器(vector、deque、list)、关联容器(map、set)、容器适配器(queue、stac)
    2013-09-09
  • Qt开发之QString类的使用教程详解

    Qt开发之QString类的使用教程详解

    本文主要介绍了Qt中QString类的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-11-11
  • C语言数据结构之单链表与双链表的增删改查操作实现

    C语言数据结构之单链表与双链表的增删改查操作实现

    这篇文章主要为大家详细介绍了C语言数据结构中单链表与双链表的增删改查操作的实现,相信大家如果搞懂了本文内容,应对复杂的链表类的题也就能慢慢钻研了
    2022-07-07
  • C++获得本机所有网卡的IP和MAC地址信息的实现方法

    C++获得本机所有网卡的IP和MAC地址信息的实现方法

    下面小编就为大家带来一篇C++获得本机所有网卡的IP和MAC地址信息的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • 深入理解C++中public、protected及private用法

    深入理解C++中public、protected及private用法

    这篇文章主要介绍了C++中public、protected及private用法,对于C++面向对象程序设计来说是非常重要的概念,需要的朋友可以参考下
    2014-08-08
  • C/C++深入讲解内存管理

    C/C++深入讲解内存管理

    本章主要介绍C语言与C++的内存管理,以C++的内存分布作为引入,介绍C++不同于C语言的内存管理方式(new delete对比 malloc free),感兴趣的朋友来看看吧
    2022-05-05

最新评论