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");

 

完毕。

时间: 2024-10-24 13:21:09

C++11之function模板和bind函数适配器的相关文章

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

function模板类和bind模板函数,使用它们可以实现类似函数指针的功能,但却却比函数指针更加灵活,特别是函数指向类 的非静态成员函数时. std::function可以绑定到全局函数/类静态成员函数(类静态成员函数与全局函数没有区别),如果要绑定到类的非静态成员函数,则需要使用std::bind #include <iostream> #include <functional> using namespace std; typedef std::function<voi

C++ bind函数适配器

在我之前的博客让类成员函数指针成为可调用对象里有提到bind函数适配器,现在在这里介绍一下. 适配器可以让某一个看上去像另一个行为,比如栈.队列等,底层使用链表去完成功能,我们通过操作底层链表去实现栈.队列等的行为.bind是函数适配器,通过bind返回的可调用对象去完成指定函数的功能. bind的头文件是<functional>,可使用命名空间std::placeholders的_n形式引用外部参数,属于C++11标准. 使用例子: // main.cpp #include <func

function/bind 函数适配器

1.function/bind简介 function是一种类模板,重载了operator()函数调用操作符,所以每一个function类的对象都是一个函数对象. bind是一种函数适配器,可以改变参数的个数.顺序. 2.相关代码 1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <functional> 5 using namespace std; 6 7 voi

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

最近开始写一个线程池,期间想用一个通用的函数模板来使得各个线程执行不同的任务,找到了Boost库中的function函数. Boost::function是一个函数包装器,也即一个函数模板,可以用来代替拥有相同返回类型,相同参数类型,以及相同参数个数的各个不同的函数. 1 #include<boost/function.hpp> 2 #include<iostream> 3 typedef boost::function<int(int ,char)> Func; 4

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

之前在http://www.cnblogs.com/inevermore/p/4008572.html中采用面向对象的方式,封装了Posix的线程,那里采用的是虚函数+继承的方式,用户通过重写Thread基类的run方法,传入自己的用户逻辑.   现在我们采用C++11的function,将函数作为Thread类的成员,用户只需要将function对象传入线程即可,所以Thread的声明中,应该含有一个function成员变量. 类的声明如下: #ifndef THREAD_H_ #define

c++11——std::function和bind绑定器

c++11中增加了std::function和std::bind,可更加方便的使用标准库,同时也可方便的进行延时求值. 可调用对象 c++中的可调用对象存在以下几类: (1)函数指针 (2)具有operator()成员函数的类对象(仿函数) (3)可被转换为函数指针的类对象 (4)类成员(函数)指针 void func(void){ //.... } struct Foo{ void operator()(void){ //... } }; struct Bar{ using fr_t = vo

C++ 11 std::function std::bind使用

cocos new 出新的项目之后,仔细阅读代码,才发现了一句3.0区别于2.0的代码: auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); 2.0内的代码用的不是CC_CALLBACK_1而是menu_selector. CC_CALLBACK系列是3.

C++11的function bind回调机制

#include <functional> using namespace std::placeholders; 1.可以提前声明函数类型:function< 返回值 ( 参数列表) >  函数名; function< int (int, double, string) > fn 也可以不用声明类型直接bind前面:auto fn = bind(  ....) 函数参数的对应: 以实际函数的参数对应声明的位置: int test(double, string, int)

以boost::function和boost:bind取代虚函数

转自:http://blog.csdn.net/Solstice/archive/2008/10/13/3066268.aspx 这是一篇比较情绪化的blog,中心思想是"继承就像一条贼船,上去就下不来了",而借助boost::function和boost::bind,大多数情况下,你都不用上贼船. boost::function和boost::bind已经纳入了std::tr1,这或许是C++0x最值得期待的功能,它将彻底改变C++库的设计方式,以及应用程序的编写方式. Scott