这部分接着之前讲过的东西,来讲variadic templates,用7个例子来深入探讨可变模板参数。
1. 一个简单的print()函数
之前讲过,见https://blog.csdn.net/oneNYT/article/details/107219042概述。
2. 使用variadic templates 重写printf()
逻辑和例子1其实一样,唯一不同的是前面有字符串指示格式,如果不匹配会抛出异常,代码如下:
template <typename T, typename... Args>
void printf(const char* s, T value, Args... args)
{
while(*s){
if(*s == '%' && *(++s) != '%'){
std::cout << value;
printf(++s, args...);
return;
}
std::cout << *s++;
}
throw std::logic_error("extra arguments provided to printf");
}
3. 使用initializer_list定义max()
如果max()要接受可变数量的参数,可以使用initializer_list或者variadic templates,如果参数类型相同,使用initializer_list即可,下面看一下标准库中的max()的例子:
//函数max()的定义
template <typename _Tp>
inline _Tp
max(initializer_list<_Tp> __l)
{
return *max_element(__l.begin(), __l.end());
}
//函数max_element()的定义
template <typename _ForwardIterator,
typename _Compare>
_ForwardIterator
__max_element(_ForwardIterator __first,
_ForwardIterator __last,
_Compare __comp)
{
if(__first == __last) return __first;
_ForwardIterator __result = __first;
while(++__first != __last)
if(__comp(__result, __first))
__result = __first;
return __result;
}
template<typename _ForwardIterator>
inline _ForwardIterator
max_element(_ForwardIterator __first,
_ForwardIterator __last)
{
return __max_element(__first, __last,
__iter_less_iter());
}
//函数__iter_less_iter()的定义
inline _Iter_less_iter
__iter_less_iter()
{ return _Iter_less_iter(); }
//类型_Iter_less_iter的定义
struct _Iter_less_iter
{
template<typename _Iterator1,
typename _Iterator2>
bool
operator()(_Iterator1 __it1,
_Iterator1 __it2) const
{ return *__it1 < *__it2; }
};
4. 参数类型相同,递归调用标准库的std::max()实现maximum()
int maximum(int n)
{
return n;
}
template<typename... Args>
int maximum(int n, Args... args)
{
return std::max(n, maximum(args...));
}
5. 为tuple重载<<运算符
//output operator for tuples
template <typename... Args>
ostream& operator<<(ostream& os, const tuple<Args...>& t){
os << "[";
PRINT_TUPLE<0, sizeof...(Args), Args...>::print(os, t);
return os << "]";
}
//print element with index IDX of tuple with MAX elements
template <int IDX, int MAX, typename... Args>
struct PRINT_TUPLE{
static void print(ostream& os, const tuple<Args...>& t){
os << get<IDX>(t) << (IDX+1 == MAX ? "" : ",");
PRINT_TUPLE<IDX+1, MAX, Args...>::print(os, t);
}
};
//partial specialization to end the recursion
template <int MAX, typename... Args>
struct PRINT_TUPLE<MAX, MAX, Args...>{
static void print(std::ostream& os, const tuple<Args...>& t){
}
};
这里关于模板的使用有点我不理解的地方:(1)类模板可以传入对象而不是类型,看起来有点像函数传参。(2)下面的偏特化版本,class后面也可以写尖括号,没见过这种写法。模板这块可能还得下点功夫。
6. tuple中的递归继承
见https://blog.csdn.net/oneNYT/article/details/107219042中第二部分的2。
7. 受6的启发,实现递归复合
template <typename... Values> class tup;
template<> class tup<> {};
template<typename Head, typename... Tail>
class tup<Head, Tail...>
{
typedef tup<Tail...> composited;
protected:
composited m_tail;
Head m_head;
public:
tup() {}
tup(Head v, Tail... vtail)
: m_tail(vtail...), m_head(v) {}
Head head() { return m_head; }
composited& tail() { return m_tail; }
};