声明:个人原创文章,禁止复制,搬运,转载
1._GET_TYPE_OR_DEFAULT(TYPE, DEFAULT)
这个宏定义于<xtr1common>
文件,根据宏函数的名字推测,该函数的功能是返回类型或者默认。
开始分析代码:
#define _GET_TYPE_OR_DEFAULT(TYPE, DEFAULT) \
{ \
template<class _Uty> \
static auto _Fn(int) \
-> _Identity<typename _Uty::TYPE>; \
\
template<class _Uty> \
static auto _Fn(_Wrap_int) \
-> _Identity<DEFAULT>; \
\
typedef decltype(_Fn<_Ty>(0)) _Decltype; \
typedef typename _Decltype::type type; \
}
首先,static auto _Fn(int) -> _Identity<typename _Uty::TYPE>;
声明了一个函数_Fn
,接受参数int
,返回参数类型为_Identity<typename _Uty::TYPE>
(这是c++11的返回类型后置语法)。看一下_Identity
的定义:
template<class _Ty>
struct _Identity
{ // map _Ty to type unchanged, without operator()
typedef _Ty type;
};
就是将模板类型_Ty映射成type。因此,这个函数的功能大概是返回函数模板参数_Uty
的TYPE
(宏函数参数1)的一个_Identity
。看到这里,还不好理解声明这个函数的用处,甚至还在疑惑为什么没有函数定义。
继续往下看。
static auto _Fn(_Wrap_int) -> _Identity<DEFAULT>;
声明了一个函数_Fn
,接受参数类型_Wrap_int
,返回类型为_Identity<DEFAULT>
。
这个函数好像是上面声明函数的重载,返回类型不一样,是一个DEFAULT
的_Identity
,参数类型也不一样,看名字猜是int的包装,看一下它的定义:
struct _Wrap_int
{ // wraps int so that int argument is favored over _Wrap_int
_Wrap_int(int)
{ // do nothing
}
};
只有一个int
的构造函数,也就是说以它为参数类型也可以接受int
类型参数。这两个函数重载都可以接受int类型参数,那如果传入一个int
类型参数,会调用哪一个函数呢?
想一想第一个函数的返回类型,模板参数是_Uty::TYPE
,那如果函数模板参数_Uty
没有TYPE
呢?而两个函数又都接受int
类型参数。因此,当传入一个int
类型时,如果_Uty::TYPE
存在,则调用前者,反之,调用后者。
继续往下看。
typedef decltype(_Fn<_Ty>(0)) _Decltype;
把_Fn<_Ty>(0)
的返回类型定义为_Decltype
,根据上面的结论,如果_Ty::TYPE
存在,那_Decltype
就是_Identity<typename _Ty::TYPE>
,否则为_Identity<DEFAULT>
。
最后一行。
typedef typename _Decltype::type type;
将_Decltype::type
定义为type,我们已经知道_Decltype
有两种可能_Identity<typename _Ty::TYPE>
和_Identity<DEFAULT>
。因此,type
有两种可能_Ty::TYPE
和DEFAULT
,当_Ty::TYPE
存在时,type
为_Ty::TYPE
,否则为DEFAULT
。
这个宏的功能也就是这样了,将_Ty::TYPE
和DEFAULT
定义成type
。现在发现,所声明的两个函数确实不需要实现,以及_Wrap_int
也不需要成员之类,因为在编译期就实现了这个宏的功能。
至于_Ty是哪里来的,随便举一个这个宏的例子:
template<class _Ty>
struct _Get_element_type
_GET_TYPE_OR_DEFAULT(element_type,
typename _Get_first_parameter<_Uty>::type);
展开后就是
template<class _Ty>
struct _Get_element_type
{
template<class _Uty>
static auto _Fn(int) -> _Identity<typename _Uty::element_type>;
template<class _Uty>
static auto _Fn(_Wrap_int) ->
_Identity<_Get_first_parameter<_Uty>::type>;
typedef decltype(_Fn<_Ty>(0)) _Decltype;
typedef typename _Decltype::type type;
}
2._HAS_TYPES(TYPE1, TYPE2, TYPE3)
源码:
#define _HAS_TYPES(TYPE1, TYPE2, TYPE3) \
{ \
template<class _Uty> \
static auto _Fn(int, \
_Identity<typename _Uty::TYPE1> * = 0, \
_Identity<typename _Uty::TYPE2> * = 0, \
_Identity<typename _Uty::TYPE3> * = 0) \
-> true_type; \
\
template<class _Uty> \
static auto _Fn(_Wrap_int) \
-> false_type; \
\
typedef decltype(_Fn<_Ty>(0)) type; \
}
有了上面的经验,我们很容易理解这个函数,也是定义两个都可以接受int
类型的函数重载,如果存在_Uty::TYPE1
、_Uty::TYPE2
和_Uty::TYPE3
就返回一个true_type
类型的值,否则返回false_type
类型的值。因此,如果_Ty
存在TYPE1
、TYPE2
和TYPE3
,type
为true_type
,否则,type
为false_type
。关于false_type
和true_type
,@todo:写文章介绍这两种类型并在这里添加链接。
3._HAS_ONE_TYPE(TYPE)
#define _HAS_ONE_TYPE(TYPE) \
_HAS_TYPES(TYPE, TYPE, TYPE)
没什么好说的了
4.struct _Has_result_type
template<class _Ty>
struct _Has_result_type
_HAS_ONE_TYPE(result_type);
也没什么说的