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;
}

GitHubhttps://github.com/fengbingchun/Messy_Test

C++11中std::function的使用的更多相关文章

  1. C++11之std::function和std::bind

    std::function是可调用对象的包装器,它最重要的功能是实现延时调用: #include "stdafx.h" #include<iostream>// std ...

  2. C++11 中的function和bind、lambda用法

    std::function 1. std::bind绑定一个成员函数 #include <iostream> #include <functional> struct Foo ...

  3. C++ 中std::function 、std::bind的使用和lambda的使用

    std::function是可调用对象的包装器:std::bind是将可点用对象和其参数一起进行绑定,且绑定后的结果可以使用std::function对象进行保存,并延迟调用到需要调用的时候: 在C+ ...

  4. 转 C++11之std::function和std::bind

    std::function是可调用对象的包装器,它最重要的功能是实现延时调用: #include "stdafx.h" #include<iostream>// std ...

  5. 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 ...

  6. 【浅析C++11】std::function和std::bind

    目录 std::function可调用对象包装器 std::function基本用法 std::function/std::bind与抽象工厂.工厂方法的一点思考 std::function可调用对象 ...

  7. C++11中std::move的使用

    std::move is used to indicate that an object t may be "moved from", i.e. allowing the effi ...

  8. C++11中std::forward的使用 (转)

    std::forward argument: Returns an rvalue reference to arg if arg is not an lvalue reference; If arg ...

  9. C++11中std::unordered_map的使用

    unordered map is an associative container that contains key-value pairs with unique keys. Search, in ...

随机推荐

  1. 开源重磅,java内容管理系统CMS,点击就可以编辑,保存,轻松构建自己的站点

    买的暂时空间不给力.内存不足,老给关闭,先转到京东云上了,免费的,也不知免费多久. 这是地址2  http://java4cms.jd-app.com/index.html 这是地址  http:// ...

  2. POJ 1379 模拟退火

    模拟退火算法,很久之前就写过一篇文章了.双倍经验题(POJ 2420) 题意: 在一个矩形区域内,求一个点的距离到所有点的距离最短的那个,最大. 这个题意,很像二分定义,但是毫无思路,也不能暴力枚举, ...

  3. CF549BLooksery Party题解

    题目描述 The Looksery company, consisting of nn staff members, is planning another big party. Every empl ...

  4. SpringMVC学习记录四——功能开发及参数绑定

    9       商品修改功能开发 9.1      需求 操作流程: 1.进入商品查询列表页面 2.点击修改,进入商品修改页面,页面中显示了要修改的商品(从数据库查询) 要修改的商品从数据库查询,根据 ...

  5. Ueditor上传图片到本地改造到上传图片到七牛云存储

    作为新手说多了都是泪啊!我特别想记录一下作为菜鸟时的坑.看看以后是否会看着笑出来. 为什么要改到云存储上就不说了.好处多多. 视频教程上使用的又拍云同时也提到了七牛云.下来我自己也查了下.又拍云是试用 ...

  6. mui的事件实现(持续更新)

    长按事件: mui('.mui-scroll').on('longtap', '.index-tab-item', function(e) { alert("长按生效") }); ...

  7. 在Azure上部署Sqlserver网络访问不了的问题

    最近在部署Azure虚拟机的时候,一直访问不了网络数据库,一搜资料才知道,Azure默认是不打开入网规则的,需要手动设置. 在 Windows 防火墙中为数据库引擎的默认实例打开 TCP 端口 在“开 ...

  8. docker官方文档翻译3

    转载请标明出处: https://blog.csdn.net/forezp/article/details/80171723 本文出自方志朋的博客 第三部分: 服务 准备工作 安装Docker 1.1 ...

  9. iOS之一些实用的Demo

    图像浏览及处理 FLAnimatedImage - gif播放处理的工具. CLImageEditor - 超强的图片编辑库,快速帮你实现旋转,防缩,滤镜等等一系列麻烦的事情. ios-image-f ...

  10. nigx配置location规则

    以下是收集的,对于不是很熟的朋友,配置转发很有帮助 1.location匹配命令和优先级: 优先级: Directives with the = prefix that match the query ...