Std::tr1::function and bind components

Source: Internet
Author: User

Use of std::tr1::function and bind components in C + +

The TR1 in C + + (technology report) contains a function template class and a bind template function, which can be used to implement functions similar to function pointers, but are more flexible than function pointers, especially when a function points to a non-static member function of a class. You can refer to Scott Meyers. <<effective C + + (3rd Edition) >>. Item 35. Specify how to use it below.

One, when you point to a global function or a static member function

Because there is essentially no difference between a global function and a static member function, the use of a method except for a static member function in the reference is preceded by the addition of the domain action classname:: Outside, there is no other difference, in fact, the global function may also be placed in the namespace, or use global domain action, such as Namespace::function () or:: function, which is not only essentially the same, the situation is also consistent with the static member functions, so they are no different, put together to discuss.

This is a simple situation where you just need to define a type

#include <iostream>

#include <iomanip>

#include <tr1/memory>

#include <tr1/functional>

typedef std::tr1::function<void (int) > handlerevent;

And then define a member variable

Class sharp{

Public

Handlerevent handlerevent;

};

The event response function can then be dynamically loaded within other functions by setting the value of the handlerevent, such as:

Class rectangle{

Private

std::string name;

Sharp Sharp;

Public

void initial (void);

Const sharp GETSHARP () const;

static void onEvent (int param) {//---------------(1)

Std::cout << "Invode onEvent method,get parameter:" << param << Std::endl;

}

};

How to implement a class

void Rectangle::initial () {

Sharp.handlerevent = Handlerevent (&rectangle::onevent); ---------------(2)

Std::cout << "Invode initial function!" << Std::endl;

}

Const Sharp RECTANGLE::GETSHARP () const{

return sharp;

}

The following is a test function:

int main (int argc,char *argv[]) {

Std::cout << "Hi:" << std::setw << "Hello world!" << Std::endl;

Rectangle Rectangle;

Rectangle.initial (); ---------------(3)

Rectangle.getsharp (). Handlerevent (23); ---------------(4)

}

The output results are as follows:

Hi:hello world!

Invode Initial function!

Invode onEvent method,get parameter:23//---------------(5)

Note that static member functions are used here, and if you remove this code from the front of the rectangle, the compilation does not work, because the static member function is not the same as the parameter table of the non-static member function, and the same non-static function has one more parameter than the static member function. The first parameter, the this pointer, to the owning object, the first argument of any non-static member function is the this pointer, so if you remove the static from the front of the rectangle, its function prototype is equivalent to one of the following global functions:

void OnEvent (rectangle* this, int);

Therefore, this does not match the function type declared by Handlerevent, and the compilation will not pass. Furthermore, since the static member function does not have this pointer, the call above (3) causes the handlerevent in the sharp object to be onevent () to the rectangle static method, so that it is executed automatically when called Through (4) (1) The static function at the OnEvent ().

Second, the use of std::tr1::bind () template function

Static member functions can be bound by the above std::tr1::function, but if you want to bind a non-static member function, you need to go to the bind () template function that will be described in the next machine.

First of all, the use of BIND, its declaration is as follows:

Bind (Function FN, T1 t1, T2 T2, ..., TN tn);

Where FN is the function that will be called, T1...TN is the parameter of the function. If you do not specify a parameter, you can use a placeholder to represent the formal parameter, with the DOT character formatted as

STD::TR1::p lacehoders::_1, std::tr1::p lacehoders::_2, ..., std::tr1::p lacehoders::_n

To change static removal before rectangle::onevent (int param) In the preceding example to a non-static member function, dynamic binding causes the program to function correctly, modifying the definition of rectangle::initial (void) to:

void Rectangle::initial () {

Sharp.handlerevent = Std::tr1::bind (&rectangle::onevent,this,std::tr1::p laceholders::_1);

Std::cout << "Invode initial function!" << Std::endl;

}

In this way, the dynamic load function succeeds. No other test data will be modified. The test results are the same.

Third, the use of pointing to the virtual member function

For virtual member functions the same as in section 2nd above, the effect of the function can still be implemented. If the definition Class square inherits from Rectangle, the rectangle::onevent overload is defined, the function in a new square::onevent,rectangle::initialize is not changed, and the Rectangle is still used: : OnEvent The input binding, when the member Object.onevent () is called, the execution rectangle::onevent or square::onevent, Depends on whether the static type of object belongs to rectangle or square.

The following is a simple example:

We first modify the initial () method above rectangle to a virtual function. Such as:

virtual void onEvent (int param) {

Std::cout << "Invode Rectangle's onEvent method,get parameter:" << param << Std::endl;

}

Then we'll write a square class to inherit the rectangle class. and override the OnEvent method. Such as:

Class Square:public rectangle{

Public

void onEvent (int param) {

Std::cout << "Invode Square ' s onEvent method,get parameter:" << param << Std::endl;

}

};

Test code:

int main (int argc,char *argv[]) {

Rectangle Rectangle;

Rectangle.initial ();

Rectangle.getsharp (). Handlerevent (23);

Square Square;

Square.initial ();

Square.getsharp (). Handlerevent (33);

}

The results after the run are as follows:

Hi:hello world!

Invode Initial function!

Invode Rectangle ' s onEvent method,get parameter:23

Invode Initial function!

Invode Square ' s onEvent method,get parameter:33

So we can see that sharp will invoke the corresponding OnEvent () method against the specific object. The above program sample reader is self-learning.

Std::tr1::function and bind components

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.