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++知识库]第三章 语言运行期强化——函数对象包裹器

3.2 函数对象包裹器

这部分虽然属于标准库的一部分,但是从本质上来看,他却增强了 C++ 语言运行时的能力。

std::function

Lambda 表达式的本质是一个和函数对象类型相似的类型的对象(有点拗口)。就是说 Lambda 表达式实际上是一种函数对象类型,这种类型称之为闭包类型。这种闭包类型产生的对象,叫做闭包对象。

当 Lambda 表达式的捕获列表为空时,闭包对象可以转换为函数指针进行值传递。如下代码:

#include <iostream>
using namespace std;

using foo = void(int);  //定义一个函数类型,前面讲过
void MyFunc(foo f)
{
    f(1);
}

int main()
{
    auto f = [](int value)
    {
        cout << value << endl;
    };
    MyFunc(f);  //传递闭包对象,隐式转换为 foo* 函数指针
    f(1);  // Lambda 表达式直接调用

    return 0;
}

在 C++11 中,统一了这些概念,将能够被调用的对象类型,统一称之为可调用类型。这种类型,就是通过 std::function 引入的。

std::function 是一种通用的、多态的函数封装,它的实例可以对任何可以调用的目标实体进行存储、复制和调用操作,它也是对 C++ 中现有的可调用实体的一种类型安全的包裹(相对来说,函数指针的调用不是类型安全的),换句话说,就是一个函数的容器。

我们有了函数的容器之后,能更加方便的将函数、函数指针作为对象进行处理。如下代码:

#include <functional>
#include <iostream>
using namespace std;

int foo(int para)
{
    return para;
}

int main()
{
    function<int(int)> func = foo;  //包装了一个返回值为 int,参数为 int 的函数
    int imporeant = 10;
    function<int(int)> func2 = [&](int value) ->int
    {
        return 1 + value + imporeant;
    };
    cout << func(10) << endl;  //输出 10
    cout << func2(10) << endl;  //输出 21
    return 0;
}

std::bind 和 std::placeholder

std::bind 用来绑定函数调用的参数的,它解决的需求是我们有时候可能并不一定能够一次性获得调用某个函数的全部参数。通过这个函数,我们可以将部分调用参数提前绑定到函数身上,成为一个新的对象,然后在参数齐全后,完成调用。如下代码:

#include <iostream>
#include <functional>

using namespace std;

int foo(int a, int b, int c)
{
    return a + b + c;
}

int main()
{
    auto bindFoo = bind(foo, placeholders::_1, 1, 2);
    //将参数 1,2 绑定到函数 foo 上,但是使用 std::placeholders::_1 来对第一个参数进行占位

    cout << bindFoo(1) << endl;  //输出 4,1 + 1 + 2 ==4

    return 0;
}

这里书上的代码有问题,书上的 foo 函数没有返回语句。C++ 不允许一个函数有返回值但是没有返回语句。

这块内容第一章说的有歧义,现已改正。

小结

不知道大家有没有学过回调函数,我感觉函数对象包裹器就是为了解决回调函数定义和调用过于麻烦的。而且用途其实和回调函数差不多。

函数对象包裹器从底层上来说就是一种函数指针。比函数指针的范围更广,可以方便的包装成员函数和仿函数。

上面的那件事,其实传统的函数指针也能做到。指针绝对是 C/C++ 语言最神奇的部分。运用指针,我们可以对底层进行更加细节的操作,细节到调用地址。

有不少人都说,C++ 在慢慢摆脱对指针的依赖,更有甚者说 C++ 应该去除指针特性,将其全部封装。

我想说,这其实就已经背离的 C++ 的初衷——自由、高效、系统级。如果没有了指针,C++ 和那些面向对象的编程语言有什么区别。

关于面向对象这件事,在《现代 C++ 白皮书》中。C++ 之父表明了,C++ 从来不是一种面向对象的编程语言,而是一门系统级编程语言。说白了,面向对象只是 C++ 的一部分。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-14 01:47:11  更:2022-01-14 01:48:20 
 
开发: 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 10:51:06-

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