在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函数适配器的更多相关文章

  1. C++11 std::function、std::bind和lambda表达式

    参考博客: C++可调用对象详解-https://www.cnblogs.com/Philip-Tell-Truth/p/5814213.html 一.关于std::function与std::bin ...

  2. std::function与std::bind 函数指针

    function模板类和bind模板函数,使用它们可以实现类似函数指针的功能,但却却比函数指针更加灵活,特别是函数指向类 的非静态成员函数时. std::function可以绑定到全局函数/类静态成员 ...

  3. 关于boost::function与boost::bind函数的使用心得

    最近开始写一个线程池,期间想用一个通用的函数模板来使得各个线程执行不同的任务,找到了Boost库中的function函数. Boost::function是一个函数包装器,也即一个函数模板,可以用来代 ...

  4. C/C++ C++ 11 std::function和std::bind用法

    std::bind() std::bind 主要用于绑定生成目标函数,一般用于生成的回调函数,cocos的回退函数都是通过std::bind和std::function实现的.两个点要明白: 1.绑定 ...

  5. JQuery实战中遇到的两个小问题$(document).ready() 、bind函数的参数传递问题

    一.$(document).ready() 与 window.onload的区别 1.执行时间 window.onload 必须等到页面内所有元素(包括图片 css js等)加载完毕后才会执行. $( ...

  6. 理解并手写 bind() 函数

    有了对call().apply()的前提分析,相信bind()我们也可以手到擒来. 参考前两篇:'对call()函数的分析' 和 '对apply()函数的分析',我们可以先得到以下代码: Functi ...

  7. c++11 符号修饰与函数签名、函数指针、匿名函数、仿函数、std::function与std::bind

    一.符号修饰与函数签名 1.符号修饰 编译器将c++源代码编译成目标文件时,用函数签名的信息对函数名进行改编,形成修饰名.GCC的C++符号修饰方法如下: 1)所有符号都以_z开头 2)名字空间的名字 ...

  8. 使用C++11的function/bind组件封装Thread以及回调函数的使用

    之前在http://www.cnblogs.com/inevermore/p/4008572.html中采用面向对象的方式,封装了Posix的线程,那里采用的是虚函数+继承的方式,用户通过重写Thre ...

  9. 利用C++11的function和bind简化类创建线程

    问题引出 当在类中需要创建线程时,总是因为线程函数需要定义成静态成员函数,但是又需要访问非静态数据成员这种需求,来做若干重复性的繁琐工作.比如我以前就经常定义一个静态成员函数,然后定一个结构体,结构体 ...

随机推荐

  1. 栅栏涂漆(color)

    栅栏涂漆测评 题目描述 zed 最近总是受到 Farmer 的困扰,因此他在自家的门前插了一排栅栏以防农气的入侵.栅栏由 N 个竖条栅栏横向组成,每个竖条栅栏宽度为 1.过了一段时间,zed 觉得栅栏 ...

  2. Qt程序crash信息的捕捉与跟踪(转)

    本文转自 https://blog.csdn.net/lanhy999/article/details/12189375

  3. glEnable(GL_DEPTH_TEST)的问题

    http://www.gameres.com/msg_195903.html 在程序中加入glEnable(GL_DEPTH_TEST)之后显示就完全黑屏了,即使是清空了深度缓冲glClear(GL_ ...

  4. 使用 Python 开始你的机器学习之旅【转】

    转自:https://linux.cn/article-8582-1.html 编译自:https://opensource.com/article/17/5/python-machine-learn ...

  5. 非常好!!!---bash转义序列笔记---打印语句printf用法【转】

    转自:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=2318684&fromuid=23571134 本教程由 惟吾无为 ...

  6. 获取a'p'p签名

    1.第一种方式 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list& ...

  7. 华农oj Problem B: Averyboy找密码【STL】

    Problem B: Averyboy找密码 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 83 Solved: 29 [Submit][Status] ...

  8. 搭建负载均衡的环境(利用虚拟机上的四台centos)

    以下转载: 准备 l 系统:Centos6  (三台) l 负载均衡:LVS  + keepalived l 服务器1:Http l 服务器2:Http ip配置 1.VIP(virtual ip): ...

  9. Intent创建Activity

    1,布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ...

  10. 集合框架(06)Arrays

    Arrays Arrays:用于操作数组的工具类,里面都是静态方法 ---数组变集合 1.asList:将数组变成List集合 把数组变成list集合的好处?可以使用集合的思想和方法来操作数组中的元素 ...