Yesterday colleagues let help write a small function, only found Cocos2d-x 3.0 and cocos2d-x 3.0rc0 difference is quite big.
Find the label of this control, 3.0 more than the RC0 version of a creation function, more critical is that the label anchor in 3.0 is in the CCP (0.5,0.5), and has been 3.0RC0 is the CCP (0,0).
Tired sleep does not love. Although the cocos2d-x change too fast, the compatibility of the exposure of a short, but, is always in the direction of good. So downloaded the 3.0来 play ~
After Cocos New project, read the code carefully before discovering a 3.0 code that is different from 2.0:
1 Auto Closeitem = menuitemimage::create (2 "Closenormal.png", 3 "Closeselected.png", 4 Cc_callback_ 1 (helloworld::menuclosecallback, 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:
1//new callbacks based on c++112 #define CC_CALLBACK_0 (__selector__,__target__, ...) std::bind (&__selector__,__ target__, # #__VA_ARGS__) 3 #define CC_CALLBACK_1 (__selector__,__target__, ...) std::bind (&__selector__,__target_ _, std::p laceholders::_1, # #__VA_ARGS__) 4 #define CC_CALLBACK_2 (__selector__,__target__, ...) std::bind (&__ SELECTOR__,__TARGET__, std::p laceholders::_1, std::p laceholders::_2, # #__VA_ARGS__) 5 #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:
1 Listener->ontouchesbegan = cc_callback_2 (Layer::ontouchesbegan, this);
At this time can not help asking Ontouchesbegan is what, why can't direct function pointer assignment?
You can see the definition.
1 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
1 int f (int, char, double); 2 Auto FF = bind (f, _1, ' C ', 1.2); The second and third parameters of the binding f () function call return a new function object for FF, which only has an int type of parameter 3 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:
1 int f (int, char, double), 2 Auto Frev = bind (f, _3, _2, _1); Flip parameter order 3 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:
1 int g (int); 2 double g (double); 3 4 Auto G1 = bind (g, _1); Error: which g () is called? 5 Auto g2 = bind (Double (*) (double)) g, _1); Right, but pretty ugly.
1 void H (int a); 2//Bind global function 3 Auto f11 = Std::bind (H, std::p laceholders::_1); 4 The type of auto is actually std::function<void (int) > 5 6//Bind the member function with Parameters 7 std::function<void (char*, int) > f = Std::bind ( &readhandler::connectpreprocess, this, std::p laceholders::_1, std::p laceholders::_1); 8 9//ternary functions are converted into unary functions of ten int f (int, char, double), 11//bound F () function call the second and third parameters, 12//Return a new function object to FF, it only has an int type parameter of the auto FF = Bind (F, _1, ' C ', 1.2); int x = FF (7);
Write your own code example as follows:
int Func (int x, int y), auto Bf1 = Std::bind (Func, ten, std::p laceholders::_1); Bf1 (20); < same as Func (ten) int helloworld::addfunc (int a, int b) { return a + b;} BOOL Helloworld::init () { Auto BF2 = Std::bind (&helloworld::addfunc,this, std::p laceholders::_1, std:: placeholders::_2); Auto RESULT1 = BF2 (10, 20); < same as A.func (TEN) std::function< int (int) > BF3 = Std::bind (&helloworld::addfunc, this, std:: Placeholders::_1, (); Auto RESULT2 = BF3 (10); < same as A.func (10, 100)}
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
1 typedef std::function<float (int x, int y) > F;//Constructs a function object, which can represent a return value of float, two parameters int,int the function 2 struct INT_DIV { //Constructs a function object type that can be called using "()" 3 Float operator () (int x, int y) const {return ((float) x)/y;}; 4}; 5 6 V OID helloworld::testing () 7 {8 F f1= int_div (); Assignment 9 Auto RESULT3 = F1 (10, 2); 10}
member functions can be considered as free functions with additional parameters:
1 struct Int_div { //Constructs a function object type that can be called using "()" 2 Float operator () (int x, int y) const {return ((float) x)/y;} ; 3 int Int_div_fun (int x) {return x;}; 4}; 5 typedef std::function<int (int_div*, int) > f_2; 6 7 bool Helloworld::init () 8 {9 f_2 F2 = STD::MEM_FN (&int_div::int_div_fun); Point to member function int_div int_div_object;12 int v = f2 (&int_div_object, 5); Call X::foo () std::function<int (int) > FF = Std::bind (F2, &int_div_object, std:) on object x with parameter 5: placeholders::_1); The first parameter of F is &x14 v = FF (5); Call X.foo (5) 15 16 17}
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.
1 struct Int_div { //Constructs a function object type that can be called using "()" 2 Float operator () (int x, int y) const {return ((float) x)/y;} ; 3 int Int_div_fun (int x) {return x;}; 4 5 int_div (std::function<void () >& f): M_callback (f) {}; 6< C7/>void Notify () 7 {8 m_callback (); 9 }10 std::function<void () > m_callback;11};
- 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.
void Foo (int x, std::function<void (int) >& f) {if (x%2==0) f (x);} void G (int x) {Cout<<x<<endl;} void H (int x) {Cout<<x+2<<endl;} void Testfoo () {Auto F = std::bind (G, std::p laceholders::_1); Foo (4, f);//change the behavior of f outside the Foo function f = 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++11 characteristics and Std::bind and std::function of Cocos2d-x 3.0