前面介绍了元函数转发的概念,也就是通过已有的元函数组合,来定义新的元函数。
如下我们实现一个元函数TypeSize用于求一个类型的size值:
template<typename T>
using TypeSize = __int(sizeof(T));
得益于__int()
是个元函数,我们通过调用它实现了TypeSize。由于上述通过调用或者组合元函数来定义新的元函数的模式非常常用,为了简化一些临时场合下的定义方式,避免每次都要为形参起名字,所以TLP库中专门定义了一组宏,用来简化元函数转发的定义方式。
// "tlp/func/Forward.h"
#define __func_forward(Name, ...) \
using Name = __VA_ARGS__
#define __func_forward_1(Name, ...) \
template<typename _1> using Name = __VA_ARGS__
#define __func_forward_2(Name, ...) \
template<typename _1, typename _2> using Name = __VA_ARGS__
#define __func_forward_3(Name, ...) \
template<typename _1, typename _2, typename _3> using Name = __VA_ARGS__
#define __func_forward_4(Name, ...) \
template<typename _1, typename _2, typename _3, typename _4> using Name = __VA_ARGS__
这组宏专门用来实现元函数转发,它默认为形参起好了从_1
开始的名称。有了这组宏,TypeSize可以如下方式定义:
__func_forward_1(TypeSize, __int(sizeof(_1)));
我们前面实现过判断一个类型是否是另一个类型的父类的元函数__is_base_of()
,我们用它实现一个新的元函数,用来在两个类型中选择出父类类型返回。
__func_forward_2(SupperOf, IfThenElse<__is_base_of(_1, _2), _1, _2>);
可以测试一下:
TEST("should_choose_the_base_type")
{
struct Base{};
struct Derived : Base{};
ASSERT_EQ(typename SupperOf<Derived, Base>::Result, Base);
}