谈的是 templateios
变化的是 template parameterless
参数个数(variable number)ide
function template
完成参数类型(different type)函数
class template
完成。void func() { /* ... */ } template <typename T, typename ... Types> void func(const T & firstArg, const Types &...args) { // 处理 firstArg func(args...); }
since C++11, template can have parameters that accepta variable number of template arguments
. This ability is called variadic template. For example, you can use the following to call printX() fora aviable number of argument of diferent types
.
(从C ++ 11开始,模板能够具备接受可变数量的模板参数的参数。 此功能称为可变参数模板。 例如,你能够使用如下代码为不一样类型的大量参数调用printX()。)布局
文件:Test.cppthis
#include <iostream> #include <bitset> using namespace std; void printX() { } template <typename T, typename ...Type> void printX(const T &firstArg, const Type &...args) { cout << sizeof...(args) << " "<< firstArg << endl; printX(args...); } int main() { printX(7.5, "hello", bitset<16>(377), 42); return 0; }
输出:spa
3 7.5 2 hello 1 0000000101111001 0 42
If one or more arguments are passed, the function template is used, which byspecifying the first argument separately
allows the first argument to print and thenrecursively
calls printX() for the remaining argument.To end the recursion, the non-template overload of printX() is provided
.
(若是传递了一个或多个参数,则使用函数模板,经过分别指定第一个参数,能够打印第一个参数,而后递归地为其他参数调用printX()。为告终束递归,提供了printX()的非模板重载。)code
使用 variadic template 重写 printf()orm
文件:Test.cpp对象
#include <iostream> namespace T { void printf(const char *s) { while (*s) { if ((*s == '%') && (*(++s) != '%')) throw std::runtime_error("invalid format string: missing argument"); std::cout << *s++; } } 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 argument provided to printf"); } } int main() { int *pi = new int{}; T::printf("%d %s %p %f\n", 15, "This is Ace", pi, 3.1415926); delete pi; return 0; }
文件:Test.cpp
#include <iostream> using namespace std; struct _Iter_less_iter { template<typename _Iterator1, typename _Iterator2> bool operator() (_Iterator1 __it1, _Iterator2 __it2) const { return *__it1 < *__it2; } }; inline _Iter_less_iter __iter_less_iter() { return _Iter_less_iter(); // 临时对象 } 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()); } template <typename _Tp> inline _Tp max(initializer_list<_Tp> __l) { return *max_element(__l.begin(), __l.end()); } int main() { cout << max({57, 48, 60, 100, 20, 18}) << endl; return 0; }
若参数类型都相同,则无需使用 variadic templates, 使用 initializer_list<T> 足够。
#include <iostream> using namespace std; namespace T { template <typename T> T max(T value) { return value; } template <typename T> T max(T lh, T rh) { return lh > rh ? lh : rh; } template <typename T, typename ...Args> T max(T value, Args ...args) { return max(value, max(args...)); } } int main() { cout << T::max(57, 48, 60, 100, 20, 18) << endl; return 0; }
文件:Test.cpp
#include <iostream> #include <tuple> #include <string> #include <bitset> using namespace std; template <int IDX, int MAX, typename ...Args> struct PRINT_TUPLE { static void print(std::ostream &os, const tuple<Args...> &t) { os << get<IDX>(t) << (IDX+1==MAX ? "" : ","); PRINT_TUPLE<IDX+1, MAX, Args...>::print(os, t); } }; // 特化实现,递归出口 template <int MAX, typename ...Args> struct PRINT_TUPLE <MAX, MAX, Args...> { static void print(ostream &os, const tuple<Args...> &t) { } }; //-------- template <typename ...Args> ostream &operator << (ostream &os, const tuple<Args...> &t) { cout << "["; PRINT_TUPLE<0, sizeof...(Args), Args...>::print(os, t); cout << "]"; return os; } int main() { cout << make_tuple(7.5, string("hello"), bitset<16>(377), 42) << endl; return 0; }
输出:
[7.5,hello,0000000101111001,42]
文件:Test.cpp
#include <iostream> #include <string> using namespace std; namespace T { // 泛型 template <typename ...Value> class tuple; // 特化出口 template <> class tuple <> { }; // 特化 template <typename Head, typename ...Tail> class tuple<Head, Tail...> : private tuple<Tail...> // 私有继承,代表两类之间不是 ‘isa’ ,仅是内存继承关机 { typedef tuple<Tail...> inherited; // using inherited=tuple<Tail...>; public: tuple() { } tuple(Head v, Tail... vtail) : inherited(vtail...), m_head(v) { } Head head() { return m_head; } inherited& tail() { return *this; } protected: Head m_head; }; } int main() { T::tuple<int, float, string> t(41, 6.3f, "nico"); cout << t.head() << endl; cout << t.tail().head() << endl; cout << t.tail().tail().head() << endl; return 0; }
输出:
41 6.3 nico
文件:Test.cpp
#include <iostream> #include <string> using namespace std; namespace T { // 泛化 template <typename ...Value> class tuple; // 特化出口 template <> class tuple <> { }; // 特化 template <typename Head, typename ...Tail> class tuple <Head, Tail...> { typedef tuple<Tail...> composited; // using composited = tuple<Tail...>; public: tuple() { } tuple(Head v, Tail... vtail) : m_tail(vtail...), m_head(v) { } Head head() { return m_head; } composited& tail() { return m_tail; } protected: composited m_tail; Head m_head; }; } int main() { T::tuple<int, float, string> t(41, 6.3f, "nico"); cout << t.head() << endl; cout << t.tail().head() << endl; cout << t.tail().tail().head() << endl; return 0; }
输出:
41 6.3 nico