缘由

看一个示例:

int add(int i, int j) { return i + j; }struct divide
{int operator()(int i, int j){ return i / j; }
};std::map<std::string, int(*)(int, int)>> ops =
{{"+", add},{"/", divide()},{"-", std::minus<int>()},{"*", [](int i, int j) {return i * j; }}
};

无法直接将ops中的可调用对象直接转换成int(*)(int, int),因为不是所有类型可以强制转换为函数指针, 编译不通过。
将上述代码修改如下,一切搞定。

std::map<std::string, std::function<int(int, int)>> ops =
{{"+", add},{"/", divide()},{"-", std::minus<int>()},{"*", [](int i, int j) {return i * j; }}
};

使用std::function的感觉就是“万众归一”。

概述

类模版std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作,这些目标实体包括普通函数、Lambda表达式、函数指针、以及其它函数对象等。std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(我们知道像函数指针这类可调用实体,是类型不安全的)。

通常std::function是一个函数对象类,它包装其它任意的函数对象,被包装的函数对象具有类型为T1, …,TN的N个参数,并且返回一个可转换到R类型的值。std::function使用 模板转换构造函数接收被包装的函数对象;特别是,闭包类型可以隐式地转换为std::function。

简单概述:通过std::function对C++中各种可调用实体(普通函数、Lambda表达式、函数指针、仿函数以及其它函数对象等)的封装,形成一个新的可调用的、统一的std::function对象。

使用方法

下面是std::function的使用示例,包括如何将普通函数、Lambda表达式、仿函数、普通成员函数、静态成员函数赋值给std::function对象。

#include <functional>
#include <iostream>int TestFunc(int a) { return a; } // 普通函数
auto lambdaFn = [](int a)->int { return a; }; // Lambda表达式class Functor // 仿函数(functor)
{public:int operator()(int a) { return a; }
};class TestClass
{public:int ClassMember(int a) { return a; } // 类成员函数static int StaticMember(int a) { return a; } // 类静态函数
};int main()
{std::function<int(int)> Functional;// 普通函数Functional = TestFunc;int result = Functional(10);std::cout << "普通函数:" << result << std::endl;// Lambda表达式Functional = lambdaFn;result = Functional(20);std::cout << "Lambda表达式:" << result << std::endl;// 仿函数Functional = Functor();result = Functional(30);std::cout << "仿函数:" << result << std::endl;// 类成员函数TestClass testObj;Functional = std::bind(&TestClass::ClassMember, testObj, std::placeholders::_1);result = Functional(40);std::cout << "普通成员函数:" << result << std::endl;// 类静态函数Functional = TestClass::StaticMember;result = Functional(50);std::cout << "静态成员函数:" << result << std::endl;return 0;
}

目的

std::function实现了一套类型消除机制,可以统一处理不同的函数对象类型。以前可以使用函数指针来完成这些(但不能完全实现);现在我们可以使用更安全的std::function来完成这些任务。

C++11 std::function类模板相关推荐

  1. C++11 std::function, std::bind, std::ref, std::cref

    C++11 std::function, std::bind, std::ref, std::cref 转自:http://www.jellythink.com/ std::function 看看这段 ...

  2. C++11 lambda表达式、function类模板、bind函数适配器

    文章目录 lambda表达式 lambda表达式的语法 lambda表达式的原理 function模板 function与重载函数 bind函数适配器 lambda表达式 当我们在写代码的时候如果经常 ...

  3. 泛型算法(lambda表达式、function类模板、bind函数适配器、迭代器类别、链表数据结构独有的算法)

    文章目录 概念 find()函数 迭代器令算法不依赖于容器 但算法依赖于元素类型的操作 算法永远不会执行容器的操作 只读算法 accumulate()函数 从两个序列中读取元素(equal函数为例) ...

  4. C++11 std::function

    @time 2019-07-07 @author Ruo_Xiao 1.头文件 #include <functional> 2.作用 类模版 std::function 是一种通用.多态的 ...

  5. c++11 std::enable_if在模板偏特化的妙用

    1.模板自动推导功能. 先看个例子: 在调用TestTemplate函数时, 我们可以在函数后面加上<类型>无歧义地指定调用的版本. 结果如下: 由于模板参数在函数参数中的位置是固定的,编 ...

  6. 可调用对象、std::function、std::bind

    可调用对象.std::function.std::bind 仿函数functors function adapter bind(C++11) 函数适配器:bind2nd 仿函数适配器(mem_fun/ ...

  7. C++11中的std::function

    文章转载自:http://www.jellythink.com/archives/771 看看这段代码 先来看看下面这两行代码: std::function<void(EventKeyboard ...

  8. C++11: std::function<void()> func

    std::function介绍 类模版std::function是一种通用.多态的函数封装.std::function的实例可以对任何可以调用的目标实体进行存储.复制.和调用操作,这些目标实体包括普通 ...

  9. C++11新特性之std::function<>

    转自http://www.jellythink.com/archives/771 看下面这两行代码: std::function<void(EventKeyboard::KeyCode, Eve ...

  10. lambda 和 std::function

    1. Lambda函数的用处 lambda 表达式可以方便地构造匿名函数,如果你的代码里面存在大量的小函数,而这些函数一般只被调用一次,那么不妨将他们重构成 lambda 表达式. C++11 的 l ...

最新文章

  1. 详解Asp.net MVC DropDownLists
  2. Google 神秘 Fuchsia OS 的开源线索
  3. java nanos_java命名空间java.util.concurrent.locks接口condition的类成员方法: awaitnanos定义及介绍...
  4. 使用HTML5的十大原因
  5. C# 多重overide
  6. hadoop可以解决什么问题_聊一聊,临时工外包可以为企业解决什么问题
  7. wordpress functions.php 在哪,在functions.php中定义变量并在WordPress中的函数钩子中访问它们...
  8. 创建 Oracle 物理备用服务器
  9. 把word地址做链接在线打开word
  10. ELK笔记(一)elasticsearch安装
  11. pandas dataframe遍历_Pandas循环提速7万多倍!Python数据分析攻略!
  12. 新手做短视频自媒体,再也不用担心找不到视频素材了,抓紧收藏
  13. php 连接timesten,timesten常见的一些简单问题
  14. kaptcha生成java验证码
  15. 【教程】如何批量制作线刷包和卡刷包
  16. 计算机网络实践报告--网络安全
  17. python合并word单元格_使用win32com合并和取消合并单元格
  18. win7忘记密码解决,Administrator账号密码忘记 解决办法
  19. epoll精粹二 - Linux C++网络编程(二十三)
  20. 兰博基尼推出全新混动超跑Revuelto

热门文章

  1. [概率论]-随机变量
  2. lenneth -- 基于koa2 的web极简框架
  3. 【IDEA】IDEA中部署的项目添加Tomcat自带的一些项目
  4. laravel中get()与 first()区别、collection与stdClass的区别
  5. 安防巨头们集体造车 跳出安防已成常态
  6. usermod+用户密码管理+mkpasswd
  7. Provisioning Services 7.8 入门系列教程之九 手动更新虚拟磁盘
  8. Windows下用C语言连接Mysql注意问题
  9. 关于作者(《蓝调口琴指南》名作拙译)
  10. 给老师的作文:育儿经验-父母是孩子最好的老师