&&&&*** 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> {...省略里面的定义和实现};
相关推荐
C++获取当前时间精确到毫秒Ms
C++获取当前时间精确到毫秒Ms
Effective Modern C++ 条款34:考虑lambda而非std::bind
无论如何,这样的理解都是值得的,因为你永远不知道何时会在阅读或维护的代码库中遇到。这是可以理解的,但是在这种情况下,改变是更好的,因为在C++11中,在C++14中,通常可以省略标准运算符模板的模板类型实参,因此无需在此处提供。进一步假设,在程序的某个时刻,我们已经确定需要设置一个小时后响30秒的警报器。(答案是传递给bind对象的所有实参都是通过引用传递的,因为此类对象的函数调用运算符使用完美转发。)等简化在C++14中的代码,其中标准后缀基于C++11对用户自定义常量的支持。的调用是通过一个函数指针。
详解C++11 线程休眠函数
C++ 11之前并未提供专门的休眠函数。c语言的sleep、usleep其实都是系统提供的函数,不同的系统函数的功能还有些差异。 在Windows系统中,sleep的参数是毫秒。 sleep(2*1000); //sleep for 2 seconds 在类Unix系统中,sleep()函数的单位是秒。 sleep(2); //sleep for 2 seconds 从C++11开始,中C++标准库提供了专门的线程休眠函数,使得你的代码可以独立于不同的平台。 std::this_thread::sleep_for std::this_thread::sleep_untill 1. 让线
VS Code 配置C++编译环境.docx
VS Code 中配置 C/C++ 编译环境,无需进行tasks.json、launch.json、c_cpp_properties.json 文件的配置
C++获取系统时间 很全面的哦
C++获取系统时间 很全面的哦 C++获取系统时间 很全面的哦



