C++11之function模板和bind函数适配器
在C++98中,可以使用函数指针,调用函数,可以参考之前的一篇文章:类的成员函数指针和mem_fun适配器的用法。
简单的函数调用
对于函数:
void foo(const string &s)
{
cout << s << endl;
}
可以使用:
void (*pFunc) (const string &) = &foo;
pFunc("bar");
现在,我们使用C++的fumction,这个函数的返回值为void,参数为const string &,所以function的模板参数为void (const string&),如下:
function<void (const string&)> f = &foo;
f("bar");
再看另外一个例子:
void foo(int i, double d)
{
cout << i << d << endl;
} int main(int argc, const char *argv[])
{
function<void (int, double)> f = &foo;
f(12, 4.5); return 0;
}
类的成员函数
下列代码:
class Foo
{
public:
void foo(int i) { cout << i << endl; } static void bar(double d) { cout << d << endl; } };
我们知道class的普通成员函数,含有一个隐式参数,而static则不然。
对于foo函数,可以使用C++98使用的mem_fun:
Foo f;
(mem_fun(&Foo::foo))(&f, 123);
现在我们使用function,但是隐式参数如何解决?我们使用bind,这是一种非常强大的函数适配器。使用方法如下:
function<void (int)> pf = bind(&Foo::foo,
&f,
std::placeholders::_1);
pf(345);
std::placeholders::_1叫做占位符,如果使用bind绑定某个值,那么该函数等于该参数消失了。如果需要保留,需要使用占位符占住位置。
在这个例子中,foo原本有两个参数,我们把隐式参数绑定某个对象地址,所以只剩下一个地址。function的模板参数为void ()。
我们也可以将两个全部占住,这样bind和mem_fun的效果是一样的:
function<void (Foo*, int)> pf2 = bind(&Foo::foo,
std::placeholders::_1,
std::placeholders::_2); pf2(&f, 456);
这里注意,_1和_2指的是实际调用的实参位置,所以我们可以通过调换_1和_2的位置实现将int和Foo*两个参数调换。
function<void (int, Foo*)> pf3 = bind(&Foo::foo,
std::placeholders::_2,
std::placeholders::_1); pf3(567, &f);
bind的灵活使用
下面通过一个更具体的例子,演示bind的用法。
void test(int i, double d, const string &s)
{
cout << "i = " << i << " d = " << d << " s = " << s << endl;
}
基本使用很简单:
function<void (int, double, const string&)> f1 = &test;
f1(12, 3.14, "foo");
1.现在将其转化为function<void (int, double)>类型。
我们分析一下:
string类型的参数消失了,所以我们需要bind一个值
其他int和double位置不变,使用_1和_2占住即可。
我们先使用
using namespace std::placeholders;
方便占位符的使用。代码如下:
function<void (int, double)> f2 =
std::bind(&test,
_1,
_2,
"foo");
2.转化为function<void (double, int, const string &)>
分析:
参数仍为3个,不需要绑定任何值。
int和double的顺序变了,所以_1为double,_2为int,注意占位符指的是实参位置。
代码:
function<void (double, int, const string &)> f3 =
std::bind(&test,
_2,
_1,
_3);
其他例子如下:
//3.void (*)(const string &, int)
function<void (const string &, int)> f4 =
std::bind(&test,
_2,
3.4,
_1); //4. void (*) (const string &, int, double)
function<void (const string&, int, double)> f5
= std::bind(&test,
_2,
_3,
_1); //5. void (*)(int)
function<void (int)> f6 =
bind(&test,
_1,
3.4,
"bar"); //6 void(*)(const string &)
function<void (const string &)> f7 =
bind(&test,
12,
4.5,
_1); //7. void (*)()
function<void()> f8 =
bind(&test,
12,
4.5,
"bar");
完毕。
C++11之function模板和bind函数适配器的更多相关文章
- C++11 std::function、std::bind和lambda表达式
参考博客: C++可调用对象详解-https://www.cnblogs.com/Philip-Tell-Truth/p/5814213.html 一.关于std::function与std::bin ...
- std::function与std::bind 函数指针
function模板类和bind模板函数,使用它们可以实现类似函数指针的功能,但却却比函数指针更加灵活,特别是函数指向类 的非静态成员函数时. std::function可以绑定到全局函数/类静态成员 ...
- 关于boost::function与boost::bind函数的使用心得
最近开始写一个线程池,期间想用一个通用的函数模板来使得各个线程执行不同的任务,找到了Boost库中的function函数. Boost::function是一个函数包装器,也即一个函数模板,可以用来代 ...
- C/C++ C++ 11 std::function和std::bind用法
std::bind() std::bind 主要用于绑定生成目标函数,一般用于生成的回调函数,cocos的回退函数都是通过std::bind和std::function实现的.两个点要明白: 1.绑定 ...
- JQuery实战中遇到的两个小问题$(document).ready() 、bind函数的参数传递问题
一.$(document).ready() 与 window.onload的区别 1.执行时间 window.onload 必须等到页面内所有元素(包括图片 css js等)加载完毕后才会执行. $( ...
- 理解并手写 bind() 函数
有了对call().apply()的前提分析,相信bind()我们也可以手到擒来. 参考前两篇:'对call()函数的分析' 和 '对apply()函数的分析',我们可以先得到以下代码: Functi ...
- c++11 符号修饰与函数签名、函数指针、匿名函数、仿函数、std::function与std::bind
一.符号修饰与函数签名 1.符号修饰 编译器将c++源代码编译成目标文件时,用函数签名的信息对函数名进行改编,形成修饰名.GCC的C++符号修饰方法如下: 1)所有符号都以_z开头 2)名字空间的名字 ...
- 使用C++11的function/bind组件封装Thread以及回调函数的使用
之前在http://www.cnblogs.com/inevermore/p/4008572.html中采用面向对象的方式,封装了Posix的线程,那里采用的是虚函数+继承的方式,用户通过重写Thre ...
- 利用C++11的function和bind简化类创建线程
问题引出 当在类中需要创建线程时,总是因为线程函数需要定义成静态成员函数,但是又需要访问非静态数据成员这种需求,来做若干重复性的繁琐工作.比如我以前就经常定义一个静态成员函数,然后定一个结构体,结构体 ...
随机推荐
- 栅栏涂漆(color)
栅栏涂漆测评 题目描述 zed 最近总是受到 Farmer 的困扰,因此他在自家的门前插了一排栅栏以防农气的入侵.栅栏由 N 个竖条栅栏横向组成,每个竖条栅栏宽度为 1.过了一段时间,zed 觉得栅栏 ...
- Qt程序crash信息的捕捉与跟踪(转)
本文转自 https://blog.csdn.net/lanhy999/article/details/12189375
- glEnable(GL_DEPTH_TEST)的问题
http://www.gameres.com/msg_195903.html 在程序中加入glEnable(GL_DEPTH_TEST)之后显示就完全黑屏了,即使是清空了深度缓冲glClear(GL_ ...
- 使用 Python 开始你的机器学习之旅【转】
转自:https://linux.cn/article-8582-1.html 编译自:https://opensource.com/article/17/5/python-machine-learn ...
- 非常好!!!---bash转义序列笔记---打印语句printf用法【转】
转自:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=2318684&fromuid=23571134 本教程由 惟吾无为 ...
- 获取a'p'p签名
1.第一种方式 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list& ...
- 华农oj Problem B: Averyboy找密码【STL】
Problem B: Averyboy找密码 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 83 Solved: 29 [Submit][Status] ...
- 搭建负载均衡的环境(利用虚拟机上的四台centos)
以下转载: 准备 l 系统:Centos6 (三台) l 负载均衡:LVS + keepalived l 服务器1:Http l 服务器2:Http ip配置 1.VIP(virtual ip): ...
- Intent创建Activity
1,布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ...
- 集合框架(06)Arrays
Arrays Arrays:用于操作数组的工具类,里面都是静态方法 ---数组变集合 1.asList:将数组变成List集合 把数组变成list集合的好处?可以使用集合的思想和方法来操作数组中的元素 ...