IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++11系列三—std::function和std::bind -> 正文阅读

[C++知识库]C++11系列三—std::function和std::bind

旧标准的缺陷

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

繁杂的调用对象

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

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

问题浮出水面

这些调用对象在使用的时候具有比较统一的时候,但是定义的方式却是五花八门。因此,C++11中为了改善这个问题,提供了std::function和std::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进行保存,并延迟调用

作用

  1. 将可调用对象与其参数一起绑定成一个仿函数
  2. 将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::bind和std::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++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 11:50:13  更:2022-04-04 11:54:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:41:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码