C++11function

C++11中增加了一些新的模板,今天我们简单介绍function模板。

头文件:<functional>

function是一个模板,当创建一个具体的function类型时,我们必须像其他类模板一样提供额外的信息。所谓的额外信息是指function类型能够表示的对象的调用形式。例如vector,我们在使用vector的时候必须要指定 vector中存放数据的类型,是int型、string型、还是double。我们必须明确指定。

function与函数指针比较相似,优点在于它允许用户在目标的实现上有更大的弹性,即目标既可以是普通函数,也可以是函数对象和类的成员函数。

一、普通函数:

首先我们给出一个普通的函数:

void foo(const string &s)
{
    cout << s << endl;
}

我们就可以在main函数中这样使用function

function<void(const string &s)> f =&foo;
f("world");

测试结果为:world。上面function可以解释为:

声明并初始化了一个function,它返回的类型为void,并接受一个const string类型的参数,并且使 f 初始化为foo函数的地址。

二、类成员函数:

我们定义一个类,代码如下:

class Foo
{
    public:
        void foo(int a)
        {
            cout << a << endl;
        }
};

我们采用了以下一种调用方式:

//头文件
#include <iostream>
#include <string>
#include <functional>
using namespace std;
//main函数
int main(int argc, const char *argv[])
{
    Foo f;
//1
    (mem_fun(&Foo::foo)(&f,123));
//2
    function<void(int)> pf =
        bind(&Foo::foo,
             &f,
             placeholders::_1);
    pf(345);
//3
    function<void(Foo*, int)> pf2 =bind(&Foo::foo,
                  std::placeholders::_1,
                  std::placeholders::_2);
    pf2(&f,345);

    return 0;
}

方式一:mem_fun,参见C++类的成员函数的指针和mem_fun适配器的用法
方式二:

function<void(int)> pf =bind(&Foo::foo, &f, placeholders::_1);

注意:

首先,bind 是一种 函数适配器 ,它可以改变参数的个数,顺序。
其次,bind中的参数依次为,类Foo的成员函数的地址、类Foo的一个对象f的地址,参数int 的占位符。

占位符_1、_2指的是实际函数调用实参的位置。而且,占位符必须是接连出现的,不可跳跃使用,bind 中的参数列表可以是 _1,_2,_3 .... 也可以是_1,_3,_2(即次序可以打乱),但是绝对不可以是这样的bind(&Foo::foo, _1, _3)

方式三:

function<void(Foo*, int)> pf2 =bind(&Foo::foo,std::placeholders::_1, std::placeholders::_2);

由于类的成员函数有个隐式参数this。所以,foo函数的实际参数有两个。
而,第三种方式把this这个隐式参数显示指出;故this对应bind中的占位符_1,int对应占位符_2.

三、实例:

#include <iostream>
#include <string>
#include <functional>
using namespace std;
using namespace std::placeholders;

void test(int i, double d, const string &s)
{
    cout << "i=" << i << " d=" << d << " s="
        << s << endl;
}

int main(int argc, const char *argv[])
{
    function<void(int, double, const string &)>f1 = &test;
    f1(1, 3.14, "foo");

//1
    //void(*)(int, double)
    function<void(double, int, const string &s)> f2 =  bind(&test, _2, _1, _3);
    f2(4.14, 2, "hello");
//2
    function<void(int, double) > f3= bind(&test, _1, _2, "world");
    f3(3, 5.14);
//3
    function<void(const string&, int )> f4 = bind(&test, _2, 6.14, _1);
    f4("how", 4);
//4
    function<void(const string&, int, double)> f5 = bind(&test, _2, _3, _1);
    f5("are", 5, 7.14);
//5
    function<void(int)> f6 = bind(&test, _1, 8.14, "you");
    f6(6);
//6
    function<void(const string &)> f7 =bind(&test, 7,9.14,_1);
    f7("thank");
//7
    function<void()> f8 = bind(&test, 8, 10.14, "foobar");
    f8();
    return 0;
}
时间: 2024-10-21 13:43:37

C++11function的相关文章

cocos2dx 3.1从零学习(三)——Touch事件(回调,反向传值)

第三讲 Touch 前面两篇我们学习的内容,足够我们做一款简单的小游戏.也可以说,我们已经入门了,可以蹒跚的走路了. 本篇将讲解cocos2dx中很重要的touch回调机制.你肯定记得第一章做定时器时间的时候用过CC_CALLBACK_1宏定义,它让我们回调一个只有一个形参的函数来执行定时操作. 回调函数的实现(Lambda表达式) 学习本篇前请仔细学习一下C++11的特性,std::function和lambda表达式.C++11还引入了很多boost库的优秀代码,使我们在使用的时候不必再加b

详解js中typeof、instanceof与constructor

详解js中typeof.instanceof与constructor typeof返回一个表达式的数据类型的字符串,返回结果为js基本的数据类型,包括number,boolean,string,object,undefined,function.语法为typeof(data) 或 typeof data instanceof则为判断一个对象是否为某一数据类型,或一个变量是否为一个对象的实例;返回boolean类型 语法为 o instanceof A 以下为综合实例: 1<script type

UVM基础之------uvm_port_base

Port Base Classes uvm_port_component_base    This class defines an interface for obtaining a port's connectivity lists after or during the end_of_elaboration phase.主要用来在end_of_elaboration phase后返回某个接口的连接列表 uvm_port_component #(PORT)    See descriptio

JavaScript新手的第一堂函数课:定义与参数(文末福利)

关注微信公众号[异步图书]每周送书 本文包括以下内容: 理解函数为何如此重要 函数为何是第一类对象 定义函数的方式 参数赋值之谜 在本文这一部分讨论JavaScript基础时,也许你会感到惊讶,我们的第一个论点是函数(function)而非对象(object).当然,第3部分会用大量笔墨解释对象,但归根结底,你要理解一些基本事实,像普通人一样编写代码和像"忍者"一样编写代码的最大差别在于是否把JavaScript作为函数式语言(functional language)来理解.对这一点的

某厂面试

1.什么是Html语义化? 语义化 div ==> section,div ==> nav(语言自己能解释), input/(关闭符号) br/ 相对于样式标记,如 i(样式)/ em(语义):b(样式)/ strong(语义); 为什么需要使用语义化标记? 1.HTML本身就是语义化标记语言,使用符合语义的标记,才谈得上正确使用HTML 2.使用合适的标记,可以合理应用浏览器默认样式 3.有利于SEO(搜索引擎的查询) 4.使用合适的标记是确保可访问性的一个前提 5.更好的可维护性 有哪些方