***** STL 原代码里面的一段看不董鸟(VS2012 版本) ************

hzhxxx 2013-08-07 06:56:34

std::function 里面的申明如下
template<class _Fty>
class function
: public _Get_function_impl<_Fty>::type
{....
};

里面使用了类 _Get_function_impl,但是类定义的时候只有一个参数,下面的宏定义,模版偏特化(专门化)_Get_function_impl 的时候,回多出很多参数。也就是有可能是这样的。

template<class _Tx> struct _Get_function_impl;
展开宏定义,有可能出现类似下面的定义
template<class _Tx,class _v0_t> struct _Get_function_impl<_Tx,_v0_t>
{
typedef _Func_class<_Ret,v0_t> type;
};

template<class _Tx,class _v0_t,class _v1_t> struct _Get_function_impl<_Tx,_v0_t,v1_t>
{
typedef _Func_class<_Tx,_v0_t,_v1_t> type;
};

这样,和第一个定义,只有一个模版参数 _Tx 的不符,这个是什么原因???




// TEMPLATE CLASS _Get_function_impl
template<class _Tx>
struct _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; \
};

#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, , , , )


...全文
573 26 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
hzhxxx 2013-08-09
  • 打赏
  • 举报
回复
问题终于搞清楚了。
sduxiaoxiang 2013-08-08
  • 打赏
  • 举报
回复
stl代码真难看、。。
hzhxxx 2013-08-08
  • 打赏
  • 举报
回复
template<class _Tx> struct _Get_function_impl; 的意思是说 _Get_function_impl 实例化的时候只能有一个模板实参。 template<class _Ret , class _V0_t> 声明新的特化可以接受数目不同的形参,但必须保证 _Get_function_impl<...> 这种特化形式的写法中 ... 只对应包含一个实参,因为这时候会检查主模板,参数个数必须一致。 template<class _Tx,class A,class B> struct _Get_function_impl<_Tx __stdcall(A,B)>{}; 这个能通过编译 template<class _Tx,class A,class B,class C> struct _Get_function_impl<_Tx __stdcall(A,B),c>{}; 这个却不能通过编译 这个整明白了,我想了也是这样。 ri_aje 说明白了。
ri_aje 2013-08-08
  • 打赏
  • 举报
回复
引用 14 楼 hzhxxx 的回复:
template<class _Tx> struct _Get_function_impl; 这个定义已经限定了最多只能有一个模版参数, 当然,这个定义是不是限定了最多只能有一个模版参数,这个原来我的理解, 难道错误了?? 但是这个定义突破了最多只能有一个的限制,现在有两个了?? template<class _Ret , class _V0_t> struct _Get_function_impl
总算看明白你问什么了。 template<class _Tx> struct _Get_function_impl; 的意思是说 _Get_function_impl 实例化的时候只能有一个模板实参。 template<class _Ret , class _V0_t> 声明新的特化可以接受数目不同的形参,但必须保证 _Get_function_impl<...> 这种特化形式的写法中 ... 只对应包含一个实参,因为这时候会检查主模板,参数个数必须一致。
hzhxxx 2013-08-08
  • 打赏
  • 举报
回复
template<class _Ret , class _V0_t> struct _Get_function_impl <_Ret __cdecl ( _V0_t ),_V0_t> { }; 这样定义却失败了!!!
hzhxxx 2013-08-08
  • 打赏
  • 举报
回复
template<class _Tx> struct _Get_function_impl; 这个定义已经限定了最多只能有一个模版参数, 当然,这个定义是不是限定了最多只能有一个模版参数,这个原来我的理解, 难道错误了?? 但是这个定义突破了最多只能有一个的限制,现在有两个了?? template<class _Ret , class _V0_t> struct _Get_function_impl
hzhxxx 2013-08-08
  • 打赏
  • 举报
回复
主要是不理解这个, template<class _Tx> struct _Get_function_impl; 已经标明了模版参数只有一个,为什么后面的申明和定义模版参数可以增加很多,比如 template<class _Ret , class _V0_t> struct _Get_function_impl<_Ret __cdecl ( _V0_t ){ typedef _Func_class<_Ret , _V0_t> type; }; 为什么后面的申明和定义模版参数可以增加很多??? 这个有点比理解??
ri_aje 2013-08-08
  • 打赏
  • 举报
回复
引用 10 楼 hzhxxx 的回复:
template<class _Tx> struct _Get_function_impl; template<class _Ret > struct _Get_function_impl<_Ret __cdecl ()> { typedef _Func_class<_Ret > type; }; 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; }; template<class _Ret , class _V0_t> struct _Get_function_impl<_Ret __cdecl ( _V0_t )> { typedef _Func_class<_Ret , _V0_t> type; }; [quote=引用 3 楼 ri_aje 的回复:] 我觉得你宏展开错误了,应该是这样

template<class _Tx,class _v0_t> 
struct _Get_function_impl<_Tx(_v0_t)> // function type
{
typedef _Func_class<_Tx,v0_t> type; 
};

template<class _Tx,class _v0_t,class _v1_t>
struct _Get_function_impl<_Tx(_v0_t,v1_t)> // function type
{
typedef _Func_class<_Tx,_v0_t,_v1_t> type; 
};
...
就是抓取函数 signature 用的,这样可以通过特化,实例化不同的 _Func_class,执行功能。
主要是不理解这个, template<class _Tx> struct _Get_function_impl; 已经标明了模版参数只有一个,为什么后面的申明和定义模版参数可以增加很多,比如 template<class _Ret , class _V0_t> struct _Get_function_impl<_Ret __cdecl ( _V0_t ){ typedef _Func_class<_Ret , _V0_t> type; }; [/quote] _Ret __cdecl ( _V0_t ) 是一个函数类型,算一个模板实参。
hzhxxx 2013-08-08
  • 打赏
  • 举报
回复
还要,增加 P 后,能通过 Debug 目录下的 .i 结尾的 预处理文件,能看到对应的宏展开,能看到相关的所有定义,包括 _Get_function_impl 但是编译通过了,连接通不过。 1>LINK : fatal error LNK1104: 无法打开文件“Debug\point_test.obj”
hzhxxx 2013-08-08
  • 打赏
  • 举报
回复
template<class _Tx> struct _Get_function_impl; template<class _Ret > struct _Get_function_impl<_Ret __cdecl ()> { typedef _Func_class<_Ret > type; }; 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; }; template<class _Ret , class _V0_t> struct _Get_function_impl<_Ret __cdecl ( _V0_t )> { typedef _Func_class<_Ret , _V0_t> type; };
引用 3 楼 ri_aje 的回复:
我觉得你宏展开错误了,应该是这样

template<class _Tx,class _v0_t> 
struct _Get_function_impl<_Tx(_v0_t)> // function type
{
typedef _Func_class<_Tx,v0_t> type; 
};

template<class _Tx,class _v0_t,class _v1_t>
struct _Get_function_impl<_Tx(_v0_t,v1_t)> // function type
{
typedef _Func_class<_Tx,_v0_t,_v1_t> type; 
};
...
就是抓取函数 signature 用的,这样可以通过特化,实例化不同的 _Func_class,执行功能。
主要是不理解这个, template<class _Tx> struct _Get_function_impl; 已经标明了模版参数只有一个,为什么后面的申明和定义模版参数可以增加很多,比如 template<class _Ret , class _V0_t> struct _Get_function_impl<_Ret __cdecl ( _V0_t ){ typedef _Func_class<_Ret , _V0_t> type; };
hzhxxx 2013-08-08
  • 打赏
  • 举报
回复
C++ 2011 STL (VS2012 Update4) 源代码阅读系列(2)]熟悉一些宏定义和模版偏特化或叫模版专门化 . http://blog.csdn.net/hzhxxx/article/details/9840511
  • 打赏
  • 举报
回复
引用 23 楼 hzhxxx 的回复:
template<class T,class ...P> T AAA(T a,P... p) { return a; } VS2012 update 4 编译通不过,看来vs2012 的最新版本还不支持变长模版参数
vs2013支持了 按照惯例来看 update中一般只会有bug修正 sp中才可能会有库的加入 大版本才会有 新的语言特性加入。
hzhxxx 2013-08-08
  • 打赏
  • 举报
回复
template<class T,class ...P> T AAA(T a,P... p) { return a; } VS2012 update 4 编译通不过,看来vs2012 的最新版本还不支持变长模版参数
hzhxxx 2013-08-08
  • 打赏
  • 举报
回复
引用 21 楼 akirya 的回复:
VS2013支持变长模板参数 代码就好看多了
template<class _Tx>
struct _Get_function_impl;


template<class _Ret, class... _Types> struct _Get_function_impl<_Ret __cdecl ( _Types... )>
{
    typedef _Func_class<_Ret, _Types...> type;
};
template<class _Ret, class... _Types> struct _Get_function_impl<_Ret __stdcall ( _Types... )>
{
    typedef _Func_class<_Ret, _Types...> type;
};
template<class _Ret, class... _Types> struct _Get_function_impl<_Ret __fastcall ( _Types... )>
{
    typedef _Func_class<_Ret, _Types...> type;
};
//专门化(偏特化)模版类,同时演示了模板继存和多模版参数应用 template<class _Fun,class v0_t,class v1_t,class v2_t,class v3_t,class v4_t> class _Bind_A<_Fun,v0_t,v1_t (),v2_t (v3_t,v4_t)> : public std::binary_function<v1_t,v2_t,bool> { private: _Fun m_v; public: _Bind_A(_Fun v):m_v(v) { // } }; _Bind_A<int,int,int(),int(int,int)> b_4(1); 不过,了解一下这个神技还是可以的。模版里面还可以这没用,关键是那个 int(),int (int,int) 在类里面真的不好怎么使用了。。。
  • 打赏
  • 举报
回复
VS2013支持变长模板参数 代码就好看多了
template<class _Tx>
struct _Get_function_impl;


template<class _Ret, class... _Types> struct _Get_function_impl<_Ret __cdecl ( _Types... )>
{
    typedef _Func_class<_Ret, _Types...> type;
};
template<class _Ret, class... _Types> struct _Get_function_impl<_Ret __stdcall ( _Types... )>
{
    typedef _Func_class<_Ret, _Types...> type;
};
template<class _Ret, class... _Types> struct _Get_function_impl<_Ret __fastcall ( _Types... )>
{
    typedef _Func_class<_Ret, _Types...> type;
};
rocktyt 2013-08-08
  • 打赏
  • 举报
回复
c++11新增的function和bind,之前都是boost那群人用非常牛逼的技术搞出来的东西,正常人还是不要浪费时间去研究比较好……很难看懂 更何况VS2012不支持变长模板,用的宏模拟的变长模板,更加难以看懂
hzhxxx 2013-08-08
  • 打赏
  • 举报
回复
引用 18 楼 sduxiaoxiang 的回复:
stl代码真难看、。。
确实,不过,不去看,更不明白里面这些规则。
Daisy__Ben 2013-08-07
  • 打赏
  • 举报
回复
欣赏LZ牛逼的勇气。别人不想你读他的代码,你偏偏要读。故弄玄虚下若干多套,你也往里跳!委员会的小伙伴们都惊呆了!
  • 打赏
  • 举报
回复
展开错了 加上 /P参数宏展开之后的代码
template<class _Tx>
struct _Get_function_impl;


template<class _Ret  > struct _Get_function_impl<_Ret __cdecl ()>
{
    typedef _Func_class<_Ret  > type;
};
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;
};
template<class _Ret , class _V0_t> struct _Get_function_impl<_Ret __cdecl ( _V0_t )>
{
    typedef _Func_class<_Ret , _V0_t> type;
};
template<class _Ret , class _V0_t> struct _Get_function_impl<_Ret __stdcall ( _V0_t )>
{
    typedef _Func_class<_Ret , _V0_t> type;
};
template<class _Ret , class _V0_t> struct _Get_function_impl<_Ret __fastcall ( _V0_t )>
{
    typedef _Func_class<_Ret , _V0_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;
};
template<class _Ret , class _V0_t , class _V1_t> struct _Get_function_impl<_Ret __fastcall ( _V0_t , _V1_t )>
{
    typedef _Func_class<_Ret , _V0_t , _V1_t> type;
};
template<class _Ret , class _V0_t , class _V1_t , class _V2_t> struct _Get_function_impl<_Ret __cdecl ( _V0_t , _V1_t , _V2_t )>
{
    typedef _Func_class<_Ret , _V0_t , _V1_t , _V2_t> type;
};
template<class _Ret , class _V0_t , class _V1_t , class _V2_t> struct _Get_function_impl<_Ret __stdcall ( _V0_t , _V1_t , _V2_t )>
{
    typedef _Func_class<_Ret , _V0_t , _V1_t , _V2_t> type;
};
template<class _Ret , class _V0_t , class _V1_t , class _V2_t> struct _Get_function_impl<_Ret __fastcall ( _V0_t , _V1_t , _V2_t )>
{
    typedef _Func_class<_Ret , _V0_t , _V1_t , _V2_t> type;
};
template<class _Ret , class _V0_t , class _V1_t , class _V2_t , class _V3_t> struct _Get_function_impl<_Ret __cdecl ( _V0_t , _V1_t , _V2_t , _V3_t )>
{
    typedef _Func_class<_Ret , _V0_t , _V1_t , _V2_t , _V3_t> type;
};
template<class _Ret , class _V0_t , class _V1_t , class _V2_t , class _V3_t> struct _Get_function_impl<_Ret __stdcall ( _V0_t , _V1_t , _V2_t , _V3_t )>
{
    typedef _Func_class<_Ret , _V0_t , _V1_t , _V2_t , _V3_t> type;
};
template<class _Ret , class _V0_t , class _V1_t , class _V2_t , class _V3_t> struct _Get_function_impl<_Ret __fastcall ( _V0_t , _V1_t , _V2_t , _V3_t )>
{
    typedef _Func_class<_Ret , _V0_t , _V1_t , _V2_t , _V3_t> type;
};
template<class _Ret , class _V0_t , class _V1_t , class _V2_t , class _V3_t , class _V4_t> struct _Get_function_impl<_Ret __cdecl ( _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;
};
template<class _Ret , class _V0_t , class _V1_t , class _V2_t , class _V3_t , class _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;
};
template<class _Ret , class _V0_t , class _V1_t , class _V2_t , class _V3_t , class _V4_t> struct _Get_function_impl<_Ret __fastcall ( _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;
};
turing-complete 2013-08-07
  • 打赏
  • 举报
回复
可以看,找个支持varidic template 的编译器看对应的源码
加载更多回复(6)

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧