I used a technical training course in the company to talk about how to expand variable template parameters, specifically how to print variable template parameters, I have a few points, there are many kinds of, below to see how many different ways to expand the variable template parameters it.
// to expand the N method of the variable parameter, take print as an example // ----notation 1template<typename t>void print (T t) { << t << Endl;} Template<typename T, TypeName ... args>void print (T-t, args ... args) { print (t); Print (args ...);
1 very ordinary, nothing special, is the standard, is also the general situation of the expansion of the way, the following to see a special point of expansion:
// ----notation 2template<typename t>void Printarg (T t) { << t << Endl;} Template<typename ... args>void print2 (args ... args) { //int a[] = {(Printarg (args), 0) ...}; std::initializer_list<int0) ...};}
The 2 is ingenious, expanded with initialization lists and comma expressions, and expands the parameter pack during the generation of the initialization list. This method is not indirect enough, I want to be able to kill the Printarg function, so the third method came out:
// ----3template<typename ... args>void print3 (args ... args) { std::initializer_list<int0) ... };}
Notation 3 simplifying writing through lambda expressions is very indirect and intuitive, and is my favorite way. So there's a 4th in addition to these three types of expansion? The answer is yes. Look at the 4th way:
//----Notation 4template<std::size_t I =0, TypeName Tuple>TypeName Std::enable_if<i = = std::tuple_size<tuple>::value>:: Type printtp (Tuple t) {//cout << "at range" << Endl;}template<std::size_t I =0, TypeName Tuple>TypeName Std::enable_if<i < std::tuple_size<tuple>::value>:: Type printtp (Tuple t) {std::cout<< std::Get<I> (t) <<Std::endl; Printtp<i +1>(t);} Template<typename ... Args>voidprint4 (args ... args) {printtp (std::make_tuple (args));}
The 4th kind of writing is also very clever, with the help of tuple and enable_if, by increasing I to get the elements in the tuple and print. At this point has completed 4 kinds of writing, there is no 5th method? The answer is yes.
//notation 5Template <intN>classPrinter { Public: Template<typename tuple>Static voidPrintConsttuple&t) {//cout << std::get<n-1> (t) << Endl;//Descendingprinter<n-1>::p rint (t); cout<< std::Get<n-1> (t) << Endl;//Ascending}};template<>classprinter<0> { Public: Template<typename tuple>Static voidPrintConsttuple&t) {}};template<typename ... Args>voidPRINT5 (Constargs&.. args) {Auto TP=std::make_tuple (args ...); Printer<sizeof... (args) >::p rint (TP);}
The implementation of the 5 way of thinking and writing 4 is similar to the good, are the use of the increment of the parameters of the int template to achieve recursion, the difference is that the writing is through the class template of the special to achieve recursion. There are 5 kinds of, there is a 6th kind? Look, the 6th kind of writing comes:
//notation 6template<int...>structindextuple{};template<intNint... Indexes>structMakeindexes:makeindexes<n-1+ I-1, indexes...>{};template<int... indexes>structmakeindexes<0, indexes...>{typedef indextuple<indexes...>type;}; Template<int... Indexes, TypeName ... Args>voidPrint_helper (INDEXTUPLE<INDEXES...>, std::tuple<args...>&&tup) {Std::initializer_list<int>{([&]{cout << std::Get<Indexes> (tup) << Endl; }(),0)...};} Template<typename ... Args>voidprint6 (args ... args) {Print_helper (typename makeindexes<sizeof... (Args) >:: Type (), Std::make_tuple (args ...));}
The 6th kind of writing is slightly complex, but it makes sense, it is actually a "redox" reaction, it is interesting and useful to convert a parameter packet to a tuple and then convert a tuple to a parameter package. At this point, we have found 6 types of expansion variable template parameters of the writing, great, you may still not do the best, there is a 7th way to write, there, but I have been too lazy to read, in fact, there are more than 7 kinds of it, that more of the wording where? There, right there, waiting for you to find out ...
Play with variadic template