[Boost Basics] bind function and callback

Source: Internet
Author: User

[Cpp] # pragma once # include <boost/bind. hpp> # include <string> # include <iostream> # include <conio. h >#include <vector >#include <algorithm> using namespace std; using namespace boost; // bind is the generalization and enhancement of the function adapters bind1st and bind2nd in the C ++ 98 standard library. It can adapt to any callable objects, including functions, function pointers, and function references, member function pointer and function object. Bind far exceeds the function binding in STL (bind1st/bind2nd). It can bind up to nine function parameters, and has very low requirements on bound objects, function objects can be bound without the result_type internal type definition. The bind library enhances the functions of the standard library. // Bind a common function (function, function pointer) int f (int a, int B) {return a + B;} // binary function int g (int a, int B, int c) {return a + B * c;} // The ternary function void test1 () {// The binding expression does not use the placeholder cout <bind (f, 1, 2 )() <endl; // 3 bind (f,) returns a function object without a parameter call, equivalent to f () cout <bind (g, 3 )() <endl; // 7 same as cout <f (1, 2) <"" <g (1, 2, 3) <endl; // 3 7 // use the placeholder int x = 0, y = 1, z = 2; cout <bind (f, _ 1, 9) (x) <endl; // 9 ==>> f (x, 9) cout <bind (f, _ 1, _ 2) (x, y) <endl; // 1 ==>> f (x, y) cout <bind (f, _ 2, _ 1) (x, y) <endl; // 1 => f (y, x) cout <bind (f, _ 1, _ 1) (x, y) <endl; // 0 => f (x, x); cout is ignored for the y parameter <bind (g, _ 2) (x, y) <endl; // 8 => g (x, 8, y) cout <bind (g, _ 3, _ 2, _ 2) (x, y, z) <endl; // 3 => g (z, y, y ); the x parameter is ignored. // All parameters required by the function must be provided in the binding expression, either real parameters or placeholders. However, you cannot use placeholders that exceed the number of function parameters. For example, you cannot use _ 3 when binding f; for binding g, you cannot use _ 4; or write bind (f, _ 1, _ 2, _ 2). Otherwise, a compilation error may occur.} // the usage of the bound function pointer is the same as above. There can be placeholders, or the placeholder typedef int (* f_type) is not used) (int, int); // The function pointer defines typedef int (* g_type) (int, int, int); // The function pointer defines void test2 () {f_type pf = f; g_type pg = g; int x = 1, y = 2, z = 3; cout <bind (pf, _ 1, 9) (x) <endl; // 10 ==>> (* pf) (x, 9) cout <bind (pg, _ 3, _ 2, _ 2) (x, y, z) <endl; // 7 ==>> (* pg) (z, y, y)} // bind the member function void test3 () {// The member functions of the class are different from Function, because the member function pointer cannot directly call opreator (), it must be bound to an object or pointer before obtaining this pointer and then calling the member function. Therefore, the position of a placeholder must be sacrificed for bind (meaning that only up to 8 parameters can be bound to member functions). Users are required to provide an instance, reference, or pointer of a class, call the member function using the first parameter of the object. Struct demo // use struct only for convenience. Do not write public {int f (int a, int B) {return a + B ;}}; demo a, & ra =, * p = & a; // Instance Object of the class, reference, pointer cout <bind (& demo: f, a, _) (10) <endl; // 30 ==>>. f () cout <bind (& demo: f, ra, _ 2, _ 1) () <endl; // 30 ==>> ra. f () cout <bind (& demo: f, p, _ 1, _ 2) () <endl; // 30 => p-> f () // note: we must add the get address operator before the member function, indicating that this is a member function pointer, otherwise, compilation fails, which is a small difference from binding a function. // Bind can bind member functions. This is a very useful function. It can replace the confusing mem_fun and mem_fun_ref bindings in the standard library and be used to operate objects in containers with standard algorithms. In the next interview, bind and standard algorithm for_each are used to call the print () function of all objects in the container: struct point {int x, y; point (int a = 0, int B = 0): x (a), y (B) {} void print () {cout <"(" <x <"," <y <") ";}}; vector <point> v (2, 3); for_each (v. begin (), v. end (), bind (& point: print, _ 1); // () // bind supports binding virtual member functions, the usage is the same as that of a non-virtual member function. The behavior of a virtual function is determined by the instance when the actual call occurs.} // Bind the function object void test4 () {// if the function object has an internal Type Definition of result_type, bind can automatically export the type of the returned value, in the same way as binding a common function. However, if the function object does not define result_type, you need to make some changes in the binding form and specify the return type using the template parameters. For example, bind <result_type> (Functor ,...) // Most function objects in the standard library and boost library have the result_type definition. Therefore, bind int x = 5, y = 2 can be directly used without any special form; // cout <bind (greater <int> (), _ 1, 10) (x) <endl; // 0 check x> 10 // cout <bind (plus <int> (), _ 1, _ 2) (x, y) <endl; // 7 run x + y // cout <bind (modulus <int> (), _ 1, 3) (x) <endl; // 2 execute x % 3 // the above three rows are okay in vs2010, but there is a problem in vs2008 // For custom function objects, if there is no result_type definition, eg struct f {int op Erator () (int a, int B) {return a + B ;}}; cout <bind <int> (f (), _ 1, _ 2) (x, y) <endl; // 7 // This method may be inconvenient. Therefore, it is best to add internal typedef result_type to the function objects when writing your own function objects, in this way, the function object works well with many other standard libraries and boost library components.} // Bind the member Variable void test5 () {struct point {int x, y; point (int a = 0, int B = 0): x (), y (B) {}void print () {cout <"(" <x <"," <y <")";}}; vector <point> v (2, 3); vector <int> v2 (2); transform (v. begin (), v. end (), v2.begin (), bind (& point: x, _ 1);} // use the ref library void test6 () {// bind stores the bound objects and parameters in the copy mode, which means that each variable in the binding expression will have a copy. If the function object or value parameter is large, the copy cost is high, or the bind cannot be copied. Therefore, the bind library can be used with the ref library. The ref library encapsulates object references and allows the bind to store object reference instances, reducing the copy cost. (The referenced object must be packaged and not destroyed.) int x = 10; cout <bind (g, _ 1, cref (x), ref (x) (10) <endl; // 110} void test (char t) {cout <"press key =" <t <endl; switch (t) {case '1': test1 (); break; case '2': test2 (); break; case '3': test3 (); break; case '4 ': test4 (); break; case '5': test5 (); break; case '6': test6 (); break; case 27: case 'q ': exit (0); break; default: cout <"default" <t <endl; break ;}int main () {while (1) {test (getch ();} return 0 ;}

Related Article

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.