[C + + STL (VS2012 Update4) source code reading Series (2)] familiar with some macro definitions and templates or template specialization

Source: Internet
Author: User
Tags function definition wrapper

[C + + STL (VS2012 Update4) source code reading Series (2)] familiar with some macro definitions and templates or template specialization


Point_test.cpp: Knowledge point exercises and tests, for single step debugging, tracking.
//

#include "stdafx.h"
#include <functional>
#include <string>
#include <iostream>

using namespace Std;
For _1, _2, _3 ...
Using namespace std::p laceholders;

Template<class t1,class t2> const T1 my_strcat (const T1, &t1,const T2)
{
return std::move (t1 + T2);
}

/*
Test examples illustrate the various combinations of std::bind and std:function and how they are invoked
If your compiler failed to compile, please remove the const as much as possible before compiling, if all is removed
or failed to compile, please upgrade your compiler to the highest version or change it.
*/
void Test_bind ()
{
std::string S1 = "AAA", s2 = "BBB", ss = "";
SS = Std::bind (MY_STRCAT&LT;STD::STRING,STD::STRING&GT;,S1,S2) ();
std::cout<<ss<<endl;
SS = my_strcat<std::string,std::string> (S1,S2);
std::cout<<ss<<endl;
Std::function<const std::string (std::string,std::string) > F1;
F1 = Std::bind (my_strcat<std::string,std::string>,_1,_2);
SS = F1 (S1,S2);
std::cout<<ss<<endl;
Std::function<std::string () > F2;
F2 = Std::bind (My_strcat<const std::string,std::string>,s1,s2);
SS = F2 ();
std::cout<<ss<<endl;
}

int _tmain (int argc, _tchar* argv[])
{
Test_bind ();

System ("pause");
return 0;
}

/* Output results are:

aaabbb
aaabbb
aaabbb
aaabbb
Please press any key to continue ...


*/

To get a better understanding of all kinds of macro definitions, let's cite an example of derivation. We're here with std::function.
Source code For example step-by-step, traced, in which various templates and macro definitions make you dizzying, amazing.
0. Overall process
Overall, the macro definition
_variadic_expand_0x (_class_get_function_impl_calls,,,,)
is a 6 macro definition
_variadic_call_opt_x1, and each _variadic_call_opt_x1 is also a definition of 3 template class _get_function_impl
So 6 *3 Total is the definition of 18 _get_function_impl

1. std::function definition
Std::function affirms the following
 //TEMPLATE CLASS function
Template<class _fty>
&nb Sp;class function
  : public _get_function_impl<_fty>::type
 { //wrapper for Callable Objects
Public:
 typedef function<_fty> _myt;
 typedef TypeName _get_function_ Impl<_fty>::type _mybase;

 function () _noexcept
  { //construct empty function wrapper
  this->_ Reset ();
  }
  
   ..... Omit the section definition and implement
&NBSP;&NBSP
  //The above code invokes the assignment function
  template<class _fx>
   _Myt& operator= (_fx&& _func)
  { //Move function object _func
   This->_tidy ();
  this->_reset (_std forward<_fx> (_func));
  return (*this);
  }
  
   ..... Omit the section definition and implement
  
Private:
 template<class _fty2>
  void operator== (const function<_fty2>&);  // not defined
 template<class _fty2>
  void operator!= (const function<_fty2>&);  // not defined
 };

We focus on affirming this sentence Template<class _fty> class function : Public _get_function_impl<_fty>::type,
 _get_function_impl<_fty>::type who can be the parent of it?
   
2.  _get_function_impl<_fty>
We continue tracing, with the following definition
Template<class _tx> struct _get_function_impl;
That's not right, the definition above should not be all _GET_FUNCTION_IMPL definitions. Where's the suspicion? Let's see the Std::function class
inside the move assignment operator Template<class _fx> _myt& operator= (_fx&& _func), The implementation inside is called
_tidy (), This->_reset (_std forward<_fx> (_func)), and these functions are not implemented in std::function there is only one possibility,
These functions are implemented within the parent class, but we see no implementation of the _get_function_impl class. Where did it go? The parent
class and the weird stuff.   Under the bear haunt, notice ...

3. Tracking _get_function_impl
We see that _get_function_impl has no implementation, and there are a few names that compare like macro definitions.
#define _CLASS_GET_FUNCTION_IMPL (\
Template_list, Padding_list, LIST, COMMA, call_opt, X2, X3, X4) \
Template<class _ret COMMA LIST (_class_type) >
struct _get_function_impl<_ret call_opt (LIST (_type)) >
{/* Determine type from argument list */
typedef _func_class<_ret COMMA LIST (_type) > TYPE; \
};

#define _CLASS_GET_FUNCTION_IMPL_CALLS (\
Template_list, Padding_list, LIST, COMMA, call_opt, X2, X3, X4) \
_variadic_call_opt_x1 (_class_get_function_impl, \
Template_list, Padding_list, LIST, COMMA, __cdecl, X2, X3, X4)

_variadic_expand_0x (_class_get_function_impl_calls,,,,)

Let's expand and see what's inside.

4. Expand _variadic_expand_0x
We keep chasing, in the file xstddef, we found its definition. Xstddef is the definition of the public STL implementation, from
The file name can clearly see the function.
For 0-x args
#define _VARIADIC_EXPAND_0X (FUNC, X1, X2, X3, X4) \
_variadic_expand_0 (FUNC, X1, X2, X3, X4) \
_variadic_expand_1x (FUNC, X1, X2, X3, X4)

Continue to expand _variadic_expand_0 and _variadic_expand_1x

We'll start the _variadic_expand_1x.
#define _VARIADIC_EXPAND_1X (FUNC, X1, X2, X3, X4) \
_variadic_expand_1 (FUNC, X1, X2, X3, X4) \
_VARIADIC_EXPAND_2X (FUNC, X1, X2, X3, X4)

Continue to expand _VARIADIC_EXPAND_2X, note that the maximum support 5 function parameters are indicated here, which is
Why Std::function supports a maximum of 5 function parameters.

#if _variadic_max = 5
#define _VARIADIC_EXPAND_2X _variadic_expand_25
#define _VARIADIC_EXPAND_25 (FUNC, X1, X2, X3, X4) \
_variadic_expand_2 (FUNC, X1, X2, X3, X4) \
_variadic_expand_3 (FUNC, X1, X2, X3, X4) \
_variadic_expand_4 (FUNC, X1, X2, X3, X4) \
_variadic_expand_5 (FUNC, X1, X2, X3, X4)

_variadic_expand_0 The final start is this definition.
Call FUNC (Template_list, Padding_list, LIST, COMMA, X1, X2, X3, X4)
#define _VARIADIC_EXPAND_0 (FUNC, X1, X2, X3, X4) \
FUNC (_tem_list0, _pad_list0, _raw_list0, X1, X2, X3, X4)

_variadic_expand_1 The final start is this definition.
#define _VARIADIC_EXPAND_1 (FUNC, X1, X2, X3, X4) \
FUNC (_tem_list1, _pad_list1, _raw_list1, _comma, X1, X2, X3, X4)

All the results came out.
#define _VARIADIC_EXPAND_2 (FUNC, X1, X2, X3, X4) \
FUNC (_tem_list2, _pad_list2, _raw_list2, _comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_3 (FUNC, X1, X2, X3, X4) \
FUNC (_tem_list3, _pad_list3, _raw_list3, _comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_4 (FUNC, X1, X2, X3, X4) \
FUNC (_tem_list4, _pad_list4, _raw_list4, _comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_5 (FUNC, X1, X2, X3, X4) \
FUNC (_tem_list5, _pad_list5, _raw_list5, _comma, X1, X2, X3, X4)

So, we get the definition of a similar _variadic_expand_ to 6 (index 0~5). They are ultimately macro definitions.
_variadic_expand_0 (_class_get_function_impl_calls,,,,)
_variadic_expand_1 (_class_get_function_impl_calls,,,,)
...
_variadic_expand_5 (_class_get_function_impl_calls,,,,)

Let's take the macro definition of index 0 as an example.
_variadic_expand_0 (_class_get_function_impl_calls,,,,) unfold, the corresponding replacement is
Call FUNC (Template_list, Padding_list, LIST, COMMA, X1, X2, X3, X4)
#define _VARIADIC_EXPAND_0 (FUNC, X1, X2, X3, X4) \
FUNC (_tem_list0, _pad_list0, _raw_list0, X1, X2, X3, X4)

After the expansion is
_variadic_expand_0 (_class_get_function_impl_calls,,,,)
It is
_class_get_function_impl_calls (_tem_list0, _pad_list0, _raw_list0, X1, X2, X3, X4)
However, after this expansion, we still do not see a definition and implementation of any class, then continue ...


5. Macro _class_get_function_impl_calls
#define _CLASS_GET_FUNCTION_IMPL_CALLS (\
Template_list, Padding_list, LIST, COMMA, call_opt, X2, X3, X4) \
_variadic_call_opt_x1 (_class_get_function_impl, \
Template_list, Padding_list, LIST, COMMA, __cdecl, X2, X3, X4)
By definition, we expand _class_get_function_impl_calls macros. Or take index 0 as an example to get the following
The definition:
_variadic_call_opt_x1 (_class_get_function_impl, _tem_list0, _pad_list0, _raw_list0,,__cdecl,x2, X3, X4)

6. Macro _variadic_call_opt_x1
Let's take a look at this embedded macro.
#define _VARIADIC_CALL_OPT_X1 (FUNC, X1, X2, X3, X4, \
Call_opt, X6, X7, X8) \
FUNC (X1, X2, X3, X4, call_opt, X6, X7, X8)
FUNC (X1, X2, X3, X4, __stdcall, X6, X7, X8)
FUNC (X1, X2, X3, X4, __fastcall, X6, X7, X8)

That actually expands to be 3 macro definitions as follows
_class_get_function_impl (_tem_list0, _pad_list0, _raw_list0, __cdecl,x2, X3, X4)
_class_get_function_impl (_tem_list0, _pad_list0, _raw_list0, __stdcall,x2, X3, X4)
_class_get_function_impl (_tem_list0, _pad_list0, _raw_list0, __fastcall,x2, X3, X4)

7. Macro _class_get_function_impl
Let's see the definition of _class_get_function_impl.
#define _CLASS_GET_FUNCTION_IMPL (\
Template_list, Padding_list, LIST, COMMA, call_opt, X2, X3, X4) \
Template<class _ret COMMA LIST (_class_type) >
struct _get_function_impl<_ret call_opt (LIST (_type)) >
{/* Determine type from argument list */
typedef _func_class<_ret COMMA LIST (_type) > TYPE; \

};

8. Get the prototype
In combination with the use of macro _class_get_function_impl, we can get a rough definition of the following, we
_class_get_function_impl (_tem_list0, _pad_list0, _raw_list0, __cdecl,x2, X3, X4)
For example exhibition:
Template<class _ret _raw_list0 (_class_type) >
struct _get_function_impl<_ret __cdecl (_raw_list0 (_type)) >
{/* Determine type from argument list */
typedef _func_class<_ret _RAW_LIST0 (_type) > TYPE; \
};

#define _RAW_LIST0 (MAP)
#define _VAR_VAL (num) _v # # num
#define _VAR_TYPE (num) _v # # NUM # # _t
#define _CLASS_TYPE (num) CLASS _var_type (num)

Template<class _ret> struct _get_function_impl<_ret __cdecl () >
{
typedef _func_class<_ret) > type;
};

That
_class_get_function_impl (_tem_list0, _pad_list0, _raw_list0, __stdcall,x2, X3, X4)
_class_get_function_impl (_tem_list0, _pad_list0, _raw_list0, __fastcall,x2, X3, X4)
corresponding is

Template<class _ret> struct _get_function_impl<_ret __stdcall () >
{
typedef _func_class<_ret) > type;
};

Template<class _ret> struct _get_function_impl<_ret __fastcall () >
{
typedef _func_class<_ret) > type;
};

9. We take _variadic_expand_2 as an example to deduce once again
By
_variadic_expand_0x (_class_get_function_impl_calls,,,,)
Start to get
#define _VARIADIC_EXPAND_2 (FUNC, X1, X2, X3, X4) \
FUNC (_tem_list2, _pad_list2, _raw_list2, _comma, X1, X2, X3, X4)
Can get
_class_get_function_impl_calls (_tem_list2, _pad_list2, _raw_list2, _comma, X1, X2, X3, X4)
And then get
_variadic_call_opt_x1 (_class_get_function_impl, _tem_list2, _pad_list2, _raw_list2, _COMMA,__cdecl, X2, X3, X4)
Continue to expand and get
_class_get_function_impl (_tem_list2,_pad_list2,_raw_list2,_comma,__cdecl,x2, X3, X4)
_class_get_function_impl (_tem_list2,_pad_list2,_raw_list2,_comma,__stdcall,x2, X3, X4)
_class_get_function_impl (_tem_list2,_pad_list2,_raw_list2,_comma,__fastcall,x2, X3, X4)
Continue to expand, get (first with __cdecl for example)
#define _CLASS_GET_FUNCTION_IMPL (\
Template_list, Padding_list, LIST, COMMA, call_opt, X2, X3, X4) \
Template<class _ret _comma _raw_list2 (_class_type) >
struct _get_function_impl<_ret __cdecl (_raw_list2 (_type)) >
{/* Determine type from argument list */
typedef _func_class<_ret _COMMA _raw_list2 (_type) > TYPE; \
};

#define _RAW_LIST2 (map) map (0) _comma map (1)
#define _RAW_LIST0 (MAP)
#define _RAW_LIST2 (map) map (0) _comma map (1)
#define _VAR_VAL (num) _v # # num
#define _VAR_TYPE (num) _v # # NUM # # _t
#define _CLASS_TYPE (num) CLASS _var_type (num)
#define _TYPE (NUM) _var_type (num)

All continues to unfold,
Template<class _ret, Class _v0_t class _v1_t>
struct _get_function_impl<_ret __cdecl (_v0_t,_v1_t)) >
{
typedef _func_class<_ret, _v0_t,_v1_t> type;
};

Template<class _ret, Class _v0_t class _v1_t>
struct _get_function_impl<_ret __cdecl (_v0_t,_v1_t)) >
{
typedef _func_class<_ret, _v0_t,_v1_t> type;
};

Template<class _ret, Class _v0_t class _v1_t>
struct _get_function_impl<_ret __stdcall (_v0_t,_v1_t)) >
{
typedef _func_class<_ret, _v0_t,_v1_t> type;
};

10. We found that
_variadic_expand_0 corresponds to a definition like this
Template<class _ret> struct _get_function_impl<_ret __stdcall () >
{
typedef _func_class<_ret) > type;
};

_variadic_expand_1 corresponds to a definition like this
Template<class _ret,_v0_t> struct _get_function_impl<_ret __stdcall (_v0_t) >
{
typedef _func_class<_ret,_v0_t) > type;
};

_variadic_expand_2 corresponds to a definition like this
Template<class _ret,_v0_t,_v1_t> struct _get_function_impl<_ret __stdcall (_v0_t,_v1_t) >
{
typedef _func_class<_ret,_v0_t,_v1_t) > type;
};

_variadic_expand_5 corresponds to a definition like this, 5 indicates that there are 5 parameters
Template<class _ret,_v0_t,_v1_t,_v2_t,_v3_t,_v4_t> struct _get_function_impl<_ret __stdcall (_V0_t,_V1_t,_ v2_t,_v3_t,_v4_t) >
{
typedef _func_class<_ret,_v0_t,_v1_t,_v2_t,_v3_t,_v4_t) > type;
};

Since then, all derivation is complete, and it is possible to understand that the class is constructed.

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.