C++11新特性之std::bind与std::function


在Cocos3.x版本中,对比之前的2.x版本,使用了很多C++11的新特性。std::function对象和std::bind机制就是其中一个。怎么把这两者联系起来呢,可以从Cocos3.x中的回调函数入手。在这之前,先来了解一下这两个的一些基础内容以及如何运作。

1、std::function
std::function是一个函数对象类,所谓函数对象类,我们可以把它当作一种表示函数的数据类型,普通的数据类型是返回数据,而它是返回一个函数对象。
function的通常形式为 std::function<F( T1, T2, … ,TN)> ,表示它包装了一个具有类型为T1,T2...TN的N个参数,返回值类型为F的函数对象。它怎么运作的呢,举个例子:

std::function<float(int x, float y)>f;   //声明函数对象f, 两个参数, 返回值为float

struct add{               //构造一个可以使用“()”进行调用的函数对象类型
        float operator()(int x,float y)
       {
        return x + y;
             };
};

f = add();
std::cout<<f(3 ,1.1);//函数对象调用

上面的例子中,我们把一个函数赋值给了一个std::function对象,然后通过函数对象来调用,这个对于回调函数十分有用,后面再说。

2、std::bind
std::bind()就是接受一个函数或者函数对象(跟std::function联系起来),然后通过绑定生成具有一个或多个参数的函数对象。通常形式为 std::bind(Func, args…) ,Func表示绑定的函数,args表示得到的函数对象所带有的参数。我们可以利用上面生成的函数对象f当作绑定的函数对象,传入std::bind中,举个例子:


     auto ff1 = std::bind(f, 1 , 3.2); //绑定f()的两个参数
     auto ff2 = std::bind(f, std::placeholders::_1 , 3.2);
     auto ff3 = std::bind(f, std::placeholders::_1, std::placeholders::_2 );
   
     std::cout<<ff1()<<std::endl;
     std::cout<<ff2(1)<<std::endl;
     std::cout<<ff3(1 ,3.2)<<std::endl;
 
std::placeholders::_1表示一个占位符对象,用于表示当函数f通过函数ff进行调用时,函数ff的第一个参数在函数f的参数列表中的位置。第一个参数称为” std::placeholders::_1″, 第二个参数为” std::placeholders::_2″,依此类推。

现在我们返回到Cocos的回调函数上,在HelloWorld中,看一下它的回调函数是怎么操作的:
首先是closeItem的创建:
 auto   closeItem =   MenuItemImage::create (
                                          
  "CloseNormal.png" ,
                                          
  "CloseSelected.png" ,
                                         
CC_CALLBACK_1(HelloWorld::menuCloseCallback,
  this));

CC_CALLBACK_1函数定义则与std::bind联系起来:
#define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)

MenuItemImage的create函数:
MenuItemImage   *   MenuItemImage::create(const   std::string& normalImage,   const   std::string& selectedImage,   const   ccMenuCallback& callback)

而回调参数ccMenuCallback则是用了std::function语法:
typedef   std::function<void(Ref*)> ccMenuCallback;
因此绕了一大圈其实就是
ccMenuCallback =  std::bind ( &HelloWorld::menuCloseCallbackthis );
所以我们在创建closeItem也可以直接使用std::bind:
auto closeItem = MenuItemImage::create (
                                           
"CloseNormal.png"
,
                                           
"CloseSelected.png",
                                           std::bind( &HelloWorld::menuCloseCallbackthis)) ;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值