博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++11之function模板和bind函数适配器
阅读量:6998 次
发布时间:2019-06-27

本文共 3081 字,大约阅读时间需要 10 分钟。

在C++98中,可以使用函数指针,调用函数,可以参考之前的一篇文章:。

 

简单的函数调用

 

对于函数:

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
f = &foo; f("bar");

再看另外一个例子:

void foo(int i, double d){    cout << i << d << endl;}int main(int argc, const char *argv[]){    function
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
pf = bind(&Foo::foo, &f, std::placeholders::_1);pf(345);

std::placeholders::_1叫做占位符,如果使用bind绑定某个值,那么该函数等于该参数消失了。如果需要保留,需要使用占位符占住位置

在这个例子中,foo原本有两个参数,我们把隐式参数绑定某个对象地址,所以只剩下一个地址。function的模板参数为void ()。

我们也可以将两个全部占住,这样bind和mem_fun的效果是一样的

function
pf2 = bind(&Foo::foo, std::placeholders::_1, std::placeholders::_2);pf2(&f, 456);

这里注意,_1和_2指的是实际调用的实参位置,所以我们可以通过调换_1和_2的位置实现将int和Foo*两个参数调换。

function
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
f1 = &test; f1(12, 3.14, "foo");

1.现在将其转化为function<void (int, double)>类型。

我们分析一下:

string类型的参数消失了,所以我们需要bind一个值

其他int和double位置不变,使用_1和_2占住即可。

我们先使用

using namespace std::placeholders;
方便占位符的使用。代码如下:
function
f2 = std::bind(&test, _1, _2, "foo");

2.转化为function<void (double, int, const string &)>

分析:

参数仍为3个,不需要绑定任何值。

int和double的顺序变了,所以_1为double,_2为int,注意占位符指的是实参位置

代码:

function
f3 = std::bind(&test, _2, _1, _3);

其他例子如下:

//3.void (*)(const string &, int)    function
f4 = std::bind(&test, _2, 3.4, _1); //4. void (*) (const string &, int, double) function
f5 = std::bind(&test, _2, _3, _1); //5. void (*)(int) function
f6 = bind(&test, _1, 3.4, "bar"); //6 void(*)(const string &) function
f7 = bind(&test, 12, 4.5, _1); //7. void (*)() function
f8 = bind(&test, 12, 4.5, "bar");

 

完毕。

转载于:https://www.cnblogs.com/inevermore/p/4032176.html

你可能感兴趣的文章
SSL连接建立过程分析(1)
查看>>
port与大全portClose方法
查看>>
美丽的数学家:如果您讨厌数学,这些其实都是人生故事
查看>>
Kettle 中转换(transformation)的执行过程
查看>>
读书笔记-互联网思维阅读10其中一本书《自由》
查看>>
Spark入门实战系列--5.Hive(上)--Hive介绍及部署
查看>>
tomcat设置web根目录
查看>>
CF 444B(DZY Loves FFT-时间复杂度)
查看>>
OCP-1Z0-051-名称解析-文章12称号
查看>>
UVALive 4225 Prime Bases 贪心
查看>>
Oracle B-tree、位图、全文索引三大索引性能比较及优缺点汇总
查看>>
[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程...
查看>>
【转】java中float与byte[]的互转 -- 不错
查看>>
[Ogre][地形][原创]基于OgreTerrain的地形实现
查看>>
shell登录模式及其相应配置文件(转)
查看>>
Puppet常识梳理
查看>>
web.config配置文件中的configSource属性
查看>>
发现一个国内牛逼的maven仓库,速度真的太快了
查看>>
Snmp配置
查看>>
使用java实现CNN的实战
查看>>