C++11中std::function的使用
class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any Callable target -- functions,lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.
There are two performance implications of using std::function that might surprise you:
(1)、When calling a std::function, it does a virtual function call.
(2)、When assigning a lambda with significant captures to a std::function, it will do a dynamic memory allocation.
类模版std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作,这些目标实体包括普通函数、Lambda表达式、函数指针、以及其它函数对象等。
通过std::function对C++中各种可调用实体(普通函数、Lambda表达式、函数指针、以及其它函数对象等)的封装,形成一个新的可调用的std::function对象,让我们不再纠结那么多的可调用实体。
std::function实现了一套类型消除机制,可以统一处理不同的函数对象类型。以前使用函数指针来完成这些,现在可以使用更安全的std::function来完成这些任务。
C++11中推出std::function是为了泛化函数对象,函数指针,引用函数,成员函数的指针,让我们可以按更统一的方式写出更加泛化的代码。
std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(像函数指针这类可调用实体,是类型不安全的)。
可调用实体转换为std::function对象需要遵守以下两条原则:
(1)、std::function对象的参数能转换为可调用实体的参数;
(2)、可调用实体的返回值能转换为std::function对象的返回值(注意,所有的可调用实体的返回值都与返回void的std::function对象的返回值兼容)。
在C++中,”可调用对象”概念:(1)、是一个函数指针;(2)、是一个具有operator()成员函数的类对象(仿函数);(3)、是一个可被转换为函数指针的类对象;(4)、是一个类成员(函数)指针。
下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:
#include "function.hpp" #include <iostream> #include <string> #include <functional> #include <vector> /////////////////////////////////////////////////////// // reference: http://en.cppreference.com/w/cpp/utility/functional/function struct Foo { Foo(int num) : num_(num) {} void print_add(int i) const { std::cout << num_ + i << '\n'; } int num_; }; void print_num(int i) { std::cout << i << '\n'; } struct PrintNum { void operator()(int i) const { std::cout << i << '\n'; } }; int test_function1() { // store a free function std::function<void(int)> f_display = print_num; f_display(-9); // store a lambda std::function<void()> f_display_42 = []() { print_num(42); }; f_display_42(); // store the result of a call to std::bind std::function<void()> f_display_31337 = std::bind(print_num, 31337); f_display_31337(); // store a call to a member function //std::function<void(const Foo&, int)> f_add_display = &Foo::print_add; const Foo foo(314159); //f_add_display(foo, 1); // store a call to a data member accessor //std::function<int(Foo const&)> f_num = &Foo::num_; //std::cout << "num_: " << f_num(foo) << '\n'; // store a call to a member function and object using std::placeholders::_1; std::function<void(int)> f_add_display2 = std::bind(&Foo::print_add, foo, _1); f_add_display2(2); // store a call to a member function and object ptr std::function<void(int)> f_add_display3 = std::bind(&Foo::print_add, &foo, _1); f_add_display3(3); // store a call to a function object std::function<void(int)> f_display_obj = PrintNum(); f_display_obj(18); return 0; } /////////////////////////////////////////////////////////// // reference: https://oopscenities.net/2012/02/24/c11-stdfunction-and-stdbind/ void execute(const std::vector<std::function<void()>>& fs) { for (auto& f : fs) f(); } void plain_old_func() { std::cout << "I'm an old plain function" << std::endl; } class functor { public: void operator()() const { std::cout << "I'm a functor" << std::endl; } }; int test_function2() { std::vector<std::function<void()>> x; x.push_back(plain_old_func); functor functor_instance; x.push_back(functor_instance); x.push_back([]() { std::cout << "HI, I'm a lambda expression" << std::endl; }); execute(x); return 0; } /////////////////////////////////////////////////////// // reference: http://shaharmike.com/cpp/lambdas-and-functions/ void global_f() { std::cout << "global_f()" << std::endl; } struct Functor { void operator()() { std::cout << "Functor" << std::endl; } }; int test_function3() { std::function<void()> f; std::cout << "sizeof(f) == " << sizeof(f) << std::endl; f = global_f; f(); f = [](){ std::cout << "Lambda" << std::endl; }; f(); Functor functor; f = functor; f(); return 0; }
GitHub:https://github.com/fengbingchun/Messy_Test
C++11中std::function的使用的更多相关文章
- C++11之std::function和std::bind
std::function是可调用对象的包装器,它最重要的功能是实现延时调用: #include "stdafx.h" #include<iostream>// std ...
- C++11 中的function和bind、lambda用法
std::function 1. std::bind绑定一个成员函数 #include <iostream> #include <functional> struct Foo ...
- C++ 中std::function 、std::bind的使用和lambda的使用
std::function是可调用对象的包装器:std::bind是将可点用对象和其参数一起进行绑定,且绑定后的结果可以使用std::function对象进行保存,并延迟调用到需要调用的时候: 在C+ ...
- 转 C++11之std::function和std::bind
std::function是可调用对象的包装器,它最重要的功能是实现延时调用: #include "stdafx.h" #include<iostream>// std ...
- C++11中std::bind的使用
std::bind: Each argument may either be bound to a value or be a placeholder: (1).If bound to a value ...
- 【浅析C++11】std::function和std::bind
目录 std::function可调用对象包装器 std::function基本用法 std::function/std::bind与抽象工厂.工厂方法的一点思考 std::function可调用对象 ...
- C++11中std::move的使用
std::move is used to indicate that an object t may be "moved from", i.e. allowing the effi ...
- C++11中std::forward的使用 (转)
std::forward argument: Returns an rvalue reference to arg if arg is not an lvalue reference; If arg ...
- C++11中std::unordered_map的使用
unordered map is an associative container that contains key-value pairs with unique keys. Search, in ...
随机推荐
- 页面三个txt加载联动省市县的代码,类似淘宝的收货地址的布局
页面三个txt加载联动省市县的代码,假如有一个树形的JSON,分别显示的省市县这时候三个TXT怎么做联动效果呢,这里用framework7为例HTML: <div class="lis ...
- 新手理解HTML、CSS、javascript之间的关系-修订
几年前写过一篇博文 <新手理解HTML.CSS.javascript之间的关系>,没想到网上出现了不少转载,当时没有太用心,里面的很多内容有待商榷,这里发布重新发布一篇. 网页主要有三部分 ...
- IDE设置jdk和maven
File->settings->Project Structure-ProjectFile->settings->Build,Execution,Deployment-> ...
- WPF学习笔记(7):DataGrid中数字自定义格式显示
DataGrid中数据显示如下图,数据格式比较杂乱.希望达到以下要求:(1)所有数据保留两位小数:(2)超过1000的数字显示千分位:(3)如果数据为0,不显示. 首先想到用StringFormat进 ...
- 运行出现Server Tomcat v8.5 Server at localhost failed to start.和A child container failed during start
出现问题: 解决方法: 1.看servlet文件中的@WebServlet“()”,里面是否少了/字符,如图: 加上即可,有问题随时留言,欢迎您的咨询!
- Linux 和类 Unix 系统上5个最佳开源备份工具
转载:http://linux.cn/article-4623-weixin.html#rd?sukey=cbbc36a2500a2e6cb7678c4d38b691a9fa7403b259f898e ...
- C#中的代码书写规范以及命名规范
C#代码书写规则: 1. 尽量使用接口,然后使用类实现接口,以提高程序的灵活性. 2.一行不要超过80个字符 3.尽量不要手动更改计算机生成的代码 4.关键的语句写注释 5.建议局部变量在最接近使用它 ...
- php第二节(变量、常量)
<?php /** * 类型转换 * 自动转换 数据在运算过程中自动转换 * 空字符串 false * "0" false * null false * 0 false * ...
- qt项目:员工信息管理系统
开发一个员工信息管理系统 一.项目具体要求: 1.用qt开发界面,数据库用QSqlite 数据库文件名:demostudent.db 2.通过界面能够查看到数据库中员工信息表中内容,包括员工姓名.年龄 ...
- TCP/IP协议模型详解
TCP