&&&&*** C++ 2011(MS版本)中 std::bind 的源代码,模版推导出现问题了???--------
世界钢铁技术头号王国卢森堡
c:\program files\microsoft visual studio 11.0\vc\include\functional
里面,调用 std::bind,里面实际上是调用了 _Bind 的构造函数,构造了一个
_Bind类返回了,我们跟踪类 _Bind 的定义,他是依赖
_VARIADIC_EXPAND_0X(_CLASS_BIND, , , , )
这个宏来定义的。
// 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)
#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)
#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)
最终展开到类定义一级,应应是6个定义,索引从 0~5
#define _VARIADIC_EXPAND_0(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST0, _PAD_LIST0, _RAW_LIST0, , X1, X2, X3, X4)
#define _VARIADIC_EXPAND_1(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _COMMA, X1, X2, X3, X4)
#define _VARIADIC_EXPAND_1(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _COMMA, X1, X2, X3, X4)
#define _VARIADIC_EXPAND_2(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _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)
类似这样的定义,应是6个定义,索引从 0~5
_CLASS_BIND(_TEM_LIST0, _PAD_LIST0, _RAW_LIST0, _COMMA, X1, X2, X3, X4)
_CLASS_BIND(_TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _COMMA, X1, X2, X3, X4)
......
_CLASS_BIND(_TEM_LIST5, _PAD_LIST5, _RAW_LIST5, _COMMA, X1, X2, X3, X4)
template<bool _Forced, class _Ret, class _Fun, _MAX_CLASS_LIST> class _Bind;
#define _CLASS_BIND( \
TEMPLATE_LIST2, PADDING_LIST2, LIST2, COMMA, X1, X2, X3, X4) \
template<bool _Forced, \
class _Ret, \
class _Fun COMMA LIST2(_CLASS_TYPEX)> \
class _Bind<_Forced, _Ret, _Fun, \
LIST2(_TYPEX) COMMA PADDING_LIST2(_NIL_PAD)> \
: public _Add_result_type<_Forced, \
_Has_result_type< \
typename decay<_Fun>::type>::type::value, \
_Ret, \
typename decay<_Fun>::type> \
{...省略里面的定义和实现};
我们展开宏_VARIADIC_EXPAND_0X,实际上应该得到6 个类似
FUNC(_TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _COMMA, X1, X2, X3, X4)
的定义,这样,最后展开,我发现这样会出现6个 _Bind 的模版类定义,
关键的是前面的 template<arg>,里面的 arg 参数个数还不一样,这样应该编译通不过的吧
#define _VARIADIC_EXPAND_ALT_05(FUNC, X1, X2, X3, X4) \
_VARIADIC_EXPAND_ALT_0(FUNC, X1, X2, X3, X4) \
_VARIADIC_EXPAND_ALT_1(FUNC, X1, X2, X3, X4) \
_VARIADIC_EXPAND_ALT_2(FUNC, X1, X2, X3, X4) \
_VARIADIC_EXPAND_ALT_3(FUNC, X1, X2, X3, X4) \
_VARIADIC_EXPAND_ALT_4(FUNC, X1, X2, X3, X4) \
#define _VARIADIC_EXPAND_ALT_2(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _COMMA, X1, X2, X3, X4)
我们以 _CLASS_BIND(_TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _COMMA, X1, X2, X3, X4) 为例展开
template<bool _Forced, class _Ret, class _Fun COMMA _RAW_LIST2(_CLASS_TYPEX)> class _Bind<_Forced, _Ret, _Fun,
_RAW_LIST2(_TYPEX) COMMA _PAD_LIST2(_NIL_PAD)> : public _Add_result_type<_Forced,
_Has_result_type<typename decay<_Fun>::type>::type::value, _Ret, typename decay<_Fun>::type> {...省略里面的定义和实现};
#define _RAW_LIST2(MAP) MAP(0) _COMMA MAP(1)
#define _PAD_LIST2 _PAD_LIST0_3
#define _PAD_LIST0_3(MAP) MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3)
#define _CLASS_TYPEX(NUM) class _VAR_TYPEX(NUM)
#define _VAR_TYPEX(NUM) _Vx ## NUM ## _t
#define _TYPEX(NUM) _VAR_TYPEX(NUM)
#define _NIL_PAD(NUM) _Nil
// STRUCT _Nil
struct _Nil
{ // empty struct, for unused argument types
};
根据上面的定义,推导出来的结果应该是
_RAW_LIST2(_CLASS_TYPEX) -> _CLASS_TYPEX(0),_CLASS_TYPEX(1) ->
class _VAR_TYPEX(0),class _VAR_TYPEX(1) -> class _Vx0_t,class _Vx1_t
_RAW_LIST2(_TYPEX) -> _TYPEX(0),_TYPEX(1)->_VAR_TYPEX(0),_VAR_TYPEX(1)->_Vx0_t,_Vx1_t
_PAD_LIST2(_NIL_PAD)->_NIL_PAD(0),_NIL_PAD(1)->_Nil,_Nil
这个就是携带两个参数的_Bind 类模版的完整定义
template<bool _Forced, class _Ret, class _Fun, class _Vx0_t,class _Vx1_t>
class _Bind<_Forced, _Ret, _Fun, _Vx0_t,_Vx1_t,_Nil,_Nil> : public _Add_result_type<_Forced,
_Has_result_type<typename decay<_Fun>::type>::type::value, _Ret, typename decay<_Fun>::type> {...省略里面的定义和实现};
很容易推导不携带参数和多个参数的定义
template<bool _Forced, class _Ret, class _Fun>
class _Bind<_Forced, _Ret, _Fun> : public _Add_result_type<_Forced,
_Has_result_type<typename decay<_Fun>::type>::type::value, _Ret, typename decay<_Fun>::type> {...省略里面的定义和实现};
template<bool _Forced, class _Ret, class _Fun, class _Vx0_t,class _Vx1_t,class _Vx2_t>
class _Bind<_Forced, _Ret, _Fun, _Vx0_t,_Vx1_t,_Vx2_t,_Nil,_Nil> : public _Add_result_type<_Forced,
_Has_result_type<typename decay<_Fun>::type>::type::value, _Ret, typename decay<_Fun>::type> {...省略里面的定义和实现};
问题出来了,模版参数个数不一致,不能通过编译啊
template<bool _Forced, class _Ret, class _Fun, _MAX_CLASS_LIST> class _Bind;
template<bool _Forced, class _Ret, class _Fun> class _Bind<_Forced, _Ret, _Fun> : public _Add_result_type<_Forced, _Has_result_type<typename decay<_Fun>::type>::type::value, _Ret, typename decay<_Fun>::type> {...省略里面的定义和实现};
template<bool _Forced, class _Ret, class _Fun, class _Vx0_t,class _Vx1_t> class _Bind<_Forced, _Ret, _Fun, _Vx0_t,_Vx1_t,_Nil,_Nil> : public _Add_result_type<_Forced, _Has_result_type<typename decay<_Fun>::type>::type::value, _Ret, typename decay<_Fun>::type> {...省略里面的定义和实现};
template<bool _Forced, class _Ret, class _Fun, class _Vx0_t,class _Vx1_t,class _Vx2_t> class _Bind<_Forced, _Ret, _Fun, _Vx0_t,_Vx1_t,_Vx2_t,_Nil,_Nil> : public _Add_result_type<_Forced, _Has_result_type<typename decay<_Fun>::type>::type::value, _Ret, typename decay<_Fun>::type> {...省略里面的定义和实现};