C + + std::function Std::bind use

Source: Internet
Author: User

After Cocos New project, read the code carefully before discovering a 3.0 code that is different from 2.0:

Auto Closeitem = menuitemimage::create (                                            "closenormal.png",                                             " Closeselected.png ",
this));

The code in 2.0 is not cc_callback_1 but menu_selector.

The Cc_callback series is a new addition to the 3.0 c++11-based features. The Cc_callback series is defined as follows:

// new callbacks based on C++11 #define Cc_callback_0 (__selector__,__target__, ...) std::bind (&__selector__,__target__, # #__VA_ARGS__)#define cc_callback_1 (__selector__,__target__, ...) std::bind (&__selector__,__target__, std::p laceholders::_1, # # __va_args__)#define cc_callback_2 (__selector__,__target__, ...) std::bind (&__selector__,__target__, std::p laceholders::_1, std::p laceholders::_2, # #__VA_ARGS__)#define cc_callback_3 (__selector__,__target_ _, ...) Std::bind (&__selector__,__target__, std::p laceholders::_1, std::p laceholders::_2, std::p laceholders::_3, # #__ VA_ARGS__)

As you can see, the number after the Cc_call_back system indicates the number of arguments to the function pointer. Understand this, when choosing Cc_callback, there will be no wrong birds.

When you look at the sample code, you'll find an interesting way to use it:

this);

At this time can not help asking Ontouchesbegan is what, why can't direct function pointer assignment?

You can see the definition.

std::function<void(const std::vector<touch*>&, event*) > Ontouchesbegan;

Because the Cc_callback series is Std::bind, and Ontouchesbegan is defined by std::function. So what's the difference between Std::bind and std::function?

There are blogs saying:

The function template class and the Bind template function, which can be used to implement functions like function pointers, are more flexible than function pointers, especially when a function is pointing to a non-static member function of a class.

Std::function can be bound to global function/class static member functions (class static member functions are not different from global functions), and if you want to bind to non-static member functions of a class, you need to use Std::bind.

The standard library functions bind () and function () are defined in the header file <functional> (which also includes many other function objects) for handling functions and function parameters.

Std::bind binding Device

    • To turn functions, member functions, and closures into function object
    • Converts a multivariate (n>1) function into a unary function or (n-1) meta function.

Bind () accepts a function (or function object, or anything you can pass through "(...)" Symbols called), which generates a function object that has one or more function arguments that are "bound" or re-organized. As the name implies, the meaning of the bind () function is like its function name, which is used to bind certain parameters of a function call. For example

int f (intchardouble'C'1.2);     // binds the second and third arguments of the F () function call, returns a new function object as FF, with only one parameter of type int int x = FF (7);                //   F (7, ' C ', 1.2);    

The binding of parameters is often referred to as "currying" (currying---"Cooking curry cooking", which means that a function or function object is processed), and "_1" is a placeholder object that is used to indicate when function f is called through the function ff. The position of the first parameter of the function ff in the argument list of the function F. The first parameter is called "_1", the second argument is "_2", and so on. For example:

int f (intchardouble= bind (f, _3, _2, _1);        // Flip Parameter Order int x = Frev (1.2'C'7);              // F (7, ' C ', 1.2);

Here, the Auto keyword saves us the effort to infer the type of result that bind returns.
We cannot bind a parameter of an overloaded function using bind (), and we must explicitly indicate the version of the overloaded function that needs to be bound:

int g (int); Double g (double= bind (g, _1);  // error: Which G () is called? Auto G2 = bind ((double(*) (double)) G, _1);    // right, but pretty ugly.    
voidHinta);//Binding Global FunctionsAuto F11 =Std::bind (H, std::p laceholders::_1), the type of auto is actually std::function<void(int) >//binding a member function with parametersstd::function<void(Char*,int) > F = Std::bind (&readhandler::connectpreprocess, This, std::p laceholders::_1, std::p laceholders::_1);//converting ternary functions into unary functionsintFint,Char,Double);//binds the second and third arguments of the F () function call,//returns a new function object for FF with only one parameter of type intAuto FF = bind (f, _1, ' C ',1.2); intx = FF (7);

Write your own code example as follows:

intFunc (intXinty); auto Bf1= Std::bind (Func,Ten, std::p laceholders::_1); Bf1 ( -);///< same as Func (Ten)intHelloworld::addfunc (intAintb) {    returnA +b;}BOOLhelloworld::init () {Auto BF2= Std::bind (&helloworld::addfunc, This, std::p laceholders::_1, std::p laceholders::_2); Auto RESULT1= BF2 (Ten, -);///< same as A.func (Ten)std::function<int(int) > BF3 = Std::bind (&helloworld::addfunc, This, std::p laceholders::_1, -); Auto Result2= BF3 (Ten);///< same as A.func (Ten)}

In the above example, BF1 is the first parameter of a two-parameter ordinary function is bound to 10, generating a new parameter of the callable body; BF2 is to bind a class member function to a class object and generate a new callable entity like a normal function; BF3 is to bind the class member function to the class object and the second parameter, resulting in a new Std::function object. To understand the above example, here are some things to note about using bind:

    • (1) Bind pre-bound parameters need to pass specific variables or values in, for the pre-bound parameters, is Pass-by-value
    • (2) For non-binding parameters, need to pass std::p laceholders go in, starting from the _1, in turn, increment. Placeholder is pass-by-reference.
    • (3) The return value of BIND is a callable entity and can be assigned directly to the Std::function object
    • (4) For binding pointers, arguments of reference types, the consumer needs to ensure that these parameters are available before callable entity calls
    • (5) The This of a class can be bound by an object or a pointer

Std::function

It is a wrapper for functions, function objects, function pointers, and member functions that can hold any type of function object, function pointer, reference function, member function pointer.
Handle functions, function objects, function pointers, and member functions in a uniform manner. Allows saving and delaying the execution of functions.

    • Functions and member functions as function

function is a owning anything that can be "(...)" The type of the value called by the symbol. In particular, the return result of bind can be assigned to the function type. function is very easy to use. More intuitively, you can think of functions as a data type that represents a function, just like a function object. Just plain data types represent data, and function represents the abstract concept of functions. For example

typedef std::function<float(intXintY) > F;//constructs a function object that can represent a function with a return value of float, two parameters of Int,intstructInt_div {//constructs a function object type that can be called by using "()"    float operator() (intXintYConst{return((float) x)/y;};};voidhelloworld::testing () {F F1= Int_div ();//Assign ValueAuto RESULT3 = F1 (Ten,2);}

member functions can be considered as free functions with additional parameters:

structInt_div {//constructs a function object type that can be called by using "()"    float operator() (intXintYConst{return((float) x)/y;}; intInt_div_fun (intx) {returnx;};}; typedef std::function<int(int_div*,int) >f_2;BOOLHelloworld::init () {f_2 F2= STD::MEM_FN (&int_div::int_div_fun);//point to member functionsInt_div Int_div_object; intv = F2 (&int_div_object,5);//call X::foo () with parameter 5 on object xstd::function<int(int) > FF = Std::bind (F2, &int_div_object, std::p laceholders::_1);//the first parameter of F is &xv = FF (5);//Call X.foo (5)}

PS: The bug that was vs2012 to the pit. Because looking at the code on the Internet, the 9th line was written like this: f_2 F2 = &int_div::int_div_fun;

Then the error is reported:Error 1 error C2664: ‘std::_Func_class<_Ret,_V0_t,_V1_t>::_Set‘ : cannot convert parameter 1 from ‘_Myimpl *‘ to ‘std::_Func_base<_Rx,_V0_t,_V1_t> *‘

Check it out, vs2010 not have this compile error, but 2012 has. 2012 must be added STD::MEM_FN to compile.

  • function pointers can be replaced with functions. Because it can hold the function deferred execution, it is more appropriate as a callback function, or it can be seen as a special delegate in C #, with only one member of the delegate.
  • structInt_div {//constructs a function object type that can be called by using "()"    float operator() (intXintYConst{return((float) x)/y;}; intInt_div_fun (intx) {returnx;}; Int_div (Std::function<void() >&f): M_callback (f) {}; voidNotify () {m_callback (); } std::function<void() >M_callback;};
  • Functions can also be used as function parameters, which allows you to control the internal behavior of functions outside the function, making our functions more flexible.
  • voidFoo (intX, std::function<void(int) >&f) {    if(%2==0) f (x);}voidGintx) {cout<<x<<Endl;}voidHintx) {cout<<x+2<<Endl;}voidTestfoo () {Auto F=Std::bind (G, std::p laceholders::_1); Foo (4, F); //change the behavior of F outside of the Foo functionf =Std::bind (H, std::p laceholders::_1); Foo (4, f);}

The function is introduced in c++11 to generalize functions, function pointers, reference functions, pointers to member functions, so that we can write more generalized code in a more uniform way, and bind is introduced to replace and enhance the bind1st and bind2st of the standard library. Let's use it more conveniently!

C + + std::function Std::bind use

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.