模板型模板参数和容器模板
事实上,C++元函数可以操作的数据包括三类:数值、类型、模板,它们通称为元数据。
模板作为元函数的输入
template< template<typename> class T1, typename T2>
struct _Func{ using type = typename T1<T2>::type; };
template <template <typename> class T1, typename T2>
using Func = typename _Func<T1, T2>::type;
Func<std::remove_reference, int&> h = 3;//元函数返回int
数学表达式:$Func(T_1, t_2) = T_1(T_2)$
元函数Func接受两个输入参数:一个模板和一个类型。将类型应用于模板之上,获取到的结果作为返回值。
模板作为元函数的输出
编写稍微复杂,实际应用较少。
// *** 元函数定义 ***
template <bool AddOrRemoveRef> struct _Func;
template<>
struct _Func<true>{//输入为true时,其输出_Func<true>::type为函数模板add_lvalue_reference
template<typename T>
using type = std::add_lvalue_reference<T>;
}
template<>
struct _Func<false>{//输入为false时,其输出_Func<true>::type为函数模板remove_reference
template<typename T>
using type = std::remove_reference<T>;
}
// *** 定义元函数简写 ***
template <typename T>
template <bool AddOrRemove>
using Func = typename _Func<AddOrRemove>::template type<T>;
// *** 调用元函数Func返回一个模板 ***
template<typename T>
using _Res = Func<false>;//函数模板,对应std::remove_reference<T>
//使用返回的模板
_Res<int&>::type h = 3;
数学表达式:$Func(addOrRemove) = T$
容器模板
可以使用一种容器来保存元数据,容器的元素可以是数值、类型、模板。
C++11中引入了变长参数模板(variadic template),使用它可以很容易地实现我们所需的容器。
template <int...Vals> struct IntContainer;//存放int
template <bool...Vals> struct BoolContainer;//存放bool
template <typename...Types> struct TypeContainer;//存放类型
template <template <typename> class...T> struct TemplateCont;//存放模板
template <template <typename...> class...T> struct TemplateCont2;//存放模板,但每个模板可以放置多个类型信息
上述的语句仅仅是声明而非定义,事实上我们可以在语句后加入大括号形成定义,但是没有必要,声明已经包含了编译器需要使用的全部信息。
参考
《C++模板元编程实战》 – 李伟
(END)