Implement boost: bind/function in vc6
Because vc6 does not support bitwise features, using boost: bind/function directly will only cause compilation errors.
The following describes how to implement the bind/function on your own.
First, let's take a look at the usage of BIND/function:
1. Bind and call a function
Int callback (int A, int B) {return a + B ;}
Int result1 = BIND (callback, 1, 2 )();
Int result2 = BIND (callback, 1) (2 );
Int result3 = BIND (callback) (1, 2 );
2. Bind and call the function object
Class callback
{
Int operator () (int A, int B) {return a + B ;}
}
Callback callback;
Int result1 = BIND (callback, 1, 2 )();
Int result2 = BIND (callback, 1) (2 );
Int result3 = BIND (callback) (1, 2 );
The returned result of BIND is a function object, which is similar to the callback above. It only adds some additional States to save the original callable object and bind it to the value of the callable object.
1 int result1 = BIND (callback, 1, 2) () the return value of BIND should be similar:
Class functionobject1
{
Public:
Int operator () {return m_callback (M_a, m_ B );}
PRIVATE:
INT (* m_callback) (int A, int B); or callback m_callback; // The original callable object.
Int M_a; // The bound value.
Int m_ B; // The bound value.
}
2 int result1 = BIND (callback, 1) (2) the return value of BIND should be similar:
Class functionobject2
{
Public:
Int operator () (int B) {return m_callback (M_a, B );}
PRIVATE:
INT (* m_callback) (int A, int B); or callback m_callback; // The original callable object.
Int M_a; // The bound value.
}
3 int result1 = BIND (callback) (1, 2) the return value of BIND should be similar:
Class functionobject3
{
Public:
Int operator () (int A, int B) {return m_callback (a, B );}
PRIVATE:
INT (* m_callback) (int A, int B); or callback m_callback; // The original callable object.
}
The problem is that bind is a template and the returned type must be represented by a template:
Template <typename treturn, typename targ1, typename targ2> class tfunctionobject1
{
Public:
Treturn operator () {return m_callback (M_a, m_ B );}
PRIVATE:
Treturn (* m_callback) (targ1 A, targ2 B); or callback m_callback; // original callable object
Targ1 M_a; // bound value
Targ2 m_ B; // bound value
}
Int callback (int A, int B) {return a + B ;}
BIND (callback, 1, 2 )();
String callback2 (string a, string B) {return a + B ;}
BIND (callback2, "1", "2 ")();
Bind implementation is as follows:
Template <typename treturn, typename targ1, typename targ2>
Tfunctionobject1 <treturn, targ1, targ2>
BIND (treturn (* function) (targ1, targ2), targ1 A, targ2 B)
{
Return tfunctionobject1 <treturn, targ1, targ2> (function, a, B );
}
The preceding implementation has two problems:
1. The first input parameter must be a callback function (you can overload bind to support more parameters), not a function object;
2. the return value of the function cannot be void, which is determined by the implementation of "Return m_callback (M_a, m_ B);" of operator () of tfunctionobject1.
The second problem in vc7 and above can be easily solved through special features:
Template <typename targ1, typename targ2> class tfunctionobject1 <void>
{
Public:
Void operator () {m_callback (M_a, m_ B );}
PRIVATE:
Void (* m_callback) (targ1 A, targ2 B); or callback m_callback; // original callable object
Targ1 M_a; // bound value
Targ2 m_ B; // bound value
}
Unfortunately, vc6 does not support special features, so you can only treat the difference between the return value and the return value:
1. return values:
Template <typename treturn, typename targ1, typename targ2> class tfunctionobject1_return
{
Public:
Treturn operator () {return m_callback (M_a, m_ B );}
PRIVATE:
Treturn (* m_callback) (targ1 A, targ2 B );
Targ1 M_a; // bound value
Targ2 m_ B; // bound value
}
Template <typename treturn, typename targ1, typename targ2>
Tfunctionobject1_return <treturn, targ1, targ2>
Bind_return (treturn (* function) (targ1, targ2), targ1 A, targ2 B)
{
Return tfunctionobject1_return <treturn, targ1, targ2> (function, a, B );
}
2. No return value:
Template <typename targ1, typename targ2> class tfunctionobject1_noreturn
{
Public:
Void operator () {m_callback (M_a, m_ B );}
PRIVATE:
Void (* m_callback) (targ1 A, targ2 B );
Targ1 M_a; // bound value
Targ2 m_ B; // bound value
}
Template <typename targ1, typename targ2>
Tfunctionobject1_noreturn <targ1, targ2>
Bind_noreturn (void (* function) (targ1, targ2), targ1 A, targ2 B)
{
Return tfunctionobject1_noreturn <targ1, targ2> (function, a, B );
}
How to determine whether the return value type of a function object is one when a function object is passed to bind. In the later version of the C ++ compiler, you can simply solve the problem through the following methods:
Template <typename tType> resultof
{
Typedef tType type;
};
Class myfunctionobject
{
Public:
String operator () (string a, string B) {return a + B ;}
};
Resultof <myfunctionobject (string, string) >:: type value = myfunctionobject (...) ("A", "B ");
It is a pity that vc6 still does not support it, so you need to take a detour.
There are two detours:
1. Special resultof for myfunctionobject:
Template <> resultof <myfunctionobject>
{
Typedef string type;
};
In this way, use resultof <myfunctionobject>: type to call the return value type using the myfunctionobject function. There is a disadvantage in doing so, that when operator () has multiple reloads, their return values must be of the same type.
2. Use the member function pointer. When a function is imported to bind, the type of the return value of the function is quite convenient. When a function object is imported, if the function pointer (string operator () is required simultaneously () (string a, string B) pointer. Unfortunately, under normal circumstances, the pointer to the operator overload function cannot be obtained (it can be obtained by playing with the memory, but we will not discuss it here ). Therefore, we need to make some changes, instead of using operator () as the function call operator, rather than using other common member functions.
Class myfunctionobject
{
Public:
String myfunctioncall (string a, string B) {return a + B ;}
Int myfunctioncall (int A, int B) {return a + B ;}
};
Implementation of passing function objects to bind
1. Special resultof
Template <typename tType> resultof
{
Typedef tType type;
};
Template <typename tfunctionobject, typename targ1, typename targ2> class tfunctionobject1_return
{
Public:
Resultof <tfunctionobject>: Type Operator () {return m_callback (M_a, m_ B );}
// The following two functions (which can be added at Will) are an additional reward for using this method: as long as the corresponding operator () is implemented in tfunctionobject, you can easily perform the overload call.
Template <typename targ3> resultof <tfunctionobject>: Type Operator () (targ3 c) {return m_callback (M_a, m_ B, c );}
Template <typename targ3, typename targ4> resultof <tfunctionobject>: Type Operator () (targ3 C, targ4 d) {return m_callback (M_a, m_ B, c, d );}
PRIVATE:
Tfunctionobject m_callback;
Targ1 M_a; // bound value
Targ2 m_ B; // bound value
}
Template <typename tfunctionobject, typename targ1, typename targ2>
Tfunctionobject1_return <tfunctionobject, targ1, targ2>
Bind_return (tfunctionobject fo, targ1 A, targ2 B)
{
Return tfunctionobject1_return <tfunctionobject, targ1, targ2> (FO, A, B );
}
/* This is an example:
Class myfunctionobject
{
Public:
String operator () (string a, string B) {return a + B ;}
String operator () (string a, string B, int c) {return a + B ;}
String operator () (string a, string B, bool c) {return a + B ;}
String operator () (string a, string B, bool C, const ctime & D) {return a + B ;}
};
Template <> resultof <myfunctionobject>
{
Typedef string type;
};
Myfunctionobject MFO;
Bind_return (MFO, "A", "B") (); // call String operator () (string a, string B)
Bind_return (MFO, "A", "B") (0); // call String operator () (string a, string B, int C)
Bind_return (MFO, "A", "B") (true); // call String operator () (string a, string B, bool C)
Bind_return (MFO, "A", "B") (true, ctime: getcurrenttime (); // call String operator () (string a, string B, bool C, const ctime & D)
//*/
2. Use the member function pointer.
Template <typename tfunctionobject, typename treturn, typename targ1, typename targ2> class tfunctionobject1_return
{
Public:
Treturn operator () {return (m_callback. * m_function) (M_a, m_ B );}
PRIVATE:
Tfunctionobject m_callback;
Treturn (tfunctionobject: m_function) (targ1, targ2 );
Targ1 M_a; // bound value
Targ2 m_ B; // bound value
}
Template <typename tfunctionobject, typename treturn, typename targ1, typename targ2>
Tfunctionobject1_return <tfunctionobject, treturn, targ1, targ2>
Bind_return (tfunctionobject fo, treturn (tfunctionobject: function) (targ1, targ2), targ1 A, targ2 B)
{
Return tfunctionobject1_return <tfunctionobject, function, targ1, targ2> (FO, A, B );
}
/* This is an example:
Class myfunctionobject
{
Public:
String myfunctioncall (string a, string B) {return a + B ;}
Int myfunctioncall2 (int A, int B) {return a + B ;}
};
Myfunctionobject MFO;
Bind_return (MFO, & myfunctionobject: myfunctioncall, "A", "B") (); // call String myfunctioncall (string a, string B)
Bind_return (MFO, & myfunctionobject: myfunctioncall2, 1, 2) (); // call int myfunctioncall2 (int A, int B)
//*/
Note that, unlike "1. Special resultof", the member functions passed in BIND in this method cannot be overloaded. Therefore, myfunctioncall and myfunctioncall2 are used in the example to distinguish between them.