【C/C++】C++11 Variadic Templates

Variadic Templates

1、function template:利用“参数个数逐一递减”的特性,实现递归函数调用

template <typename T, typename... Types>
void func(const T& firstArg, const Types&... args) {
    处理 firstArg
    func(args...);
}

例一、实现类似 python 3 的 print()

 1 void print() { cout << endl; }    // 边界条件,当args为0个时调用
 2 
 3 template <typename T, typename... Types>
 4 void print(const T& firstArg, const Types&... args) {  
 5     cout << firstArg << ' ';
 6     print(args...);
 7 }
 8 
 9 int main() {
10     print(7.5, "hello", bitset<16>(377), 42);    // print "7.5 hello 0000000101111001 42"
11     return 0;
12 }

如果同时存在函数

template <typename... Types>
void print(const Types&... args) {
    ...
}

void print(const T& firstArg, const Types&... args) 与 void print(const Types&... args) 可以共存,可以编译通过。

但前者比较特化,后者比较泛化,共存时永远不会调用后者。

例二、模拟 C <cstdio> 的 printf(),引自 stackoverflow

 1 void Printf(const char* s) {
 2     while (*s) {
 3         if (*s == '%' && *(++s) != '%')
 4             throw runtime_error("invalid format string: missing arguments.");
 5         cout << *s++; 
 6     }
 7 }
 8 
 9 template <typename T, typename... Types>
10 void Printf(const char* s, const T& firstArg, const Types&... args) {
11     while (*s) {
12         if (*s == '%' && *(++s) != '%') {
13             cout << firstArg;
14             Printf(++s, args...);
15             return;
16         }
17         cout << *s++;
18     }
19 }
20 
21 int main() {
22     int* pi = new int;
23     Printf("[%p] %s = %f
", pi, "This is pi", 3.1415926);    // print "[0x21fcc20] This is pi = 3.14159"
24     return 0;
25 }

2、class template:利用“参数个数逐一递减”导致“参数类型也逐一递减”的特性,实现递归继承或递归复合

例一、对 first 和 last(头尾元素)的特别处理(模板偏特化+递归)

 1 // 使用tuple index和max index打印元素
 2 template <int IDX, int MAX, typename... Args>
 3 struct print_tuple {
 4     static void print(ostream& os, const tuple<Args...>& args) {
 5         os << get<IDX>(args) << (IDX + 1 == MAX ? "" : ", ");
 6         print_tuple<IDX + 1, MAX, Args...>::print(os, args);
 7     }
 8 };
 9 
10 // 递归结束的偏特化
11 template <int MAX, typename... Args>
12 struct print_tuple<MAX, MAX, Args...> {
13     static void print(ostream&, const tuple<Args...>&) {}
14 };
15 
16 // output operator for tuple 
17 template <typename... Args>
18 ostream& operator<<(ostream& os, const tuple<Args...>& args) {
19     os << '[';
20     // 需要知道tuple的元素index,用sizeof...(Args)获得元素个数
21     print_tuple<0, sizeof...(Args), Args...>::print(os, args);
22     return os << ']';
23 }
24 
25 int main() {
26     cout << make_tuple(7.5, string("hello"), bitset<16>(377), 42);    // print "[7.5, hello, 0000000101111001, 42]"
27     return 0;
28 }

例二、C++STL 中 tuple 的实现(类的递归继承)

template <typename... Values> class tuple;
template <> class tuple<> { };

template <typename Head, typename... Tail>
class tuple<Head, Tail...> : private tuple <Tail...> {
    typedef tuple<Tail...> inherited;
public:
    tuple() { }
    tuple(Head v, Tail... vtail) : m_head(v), inherited(vtail...) { }    // 调用base ctor
    ...
protected:
    Head m_head;
};

 

例三、模拟 tuple(类的递归复合)

template <typename... Values> class tup;
template <> class tup<> { };

template <typename Head, typename... Tail>
class tup<Head, Tail...> {
    typedef tup<Tail...> composited;
public:
    tup() { }
    tup(Head v, Tail... vtail) : m_head(v), m_tail(vtail...) { }    // 递归复合
    ...
protected:
    Head m_head;
    composited m_tail;
};

只是这种实现 tuple 的方式内存消耗较大

原文地址:https://www.cnblogs.com/wayne793377164/p/9104862.html