Using variable template parameters to implement the log function

Source: Internet
Author: User

In a previous blog post, a similar topic was written. The following method is used.

TT& t){    ‘\n‘T...T... args){    ‘ ‘;    logOld(args...);}

function calls have recursion, and templates can have recursion when they are expanded. In writing a recursive function, we need to find the exit of the recursion so that it does not fall into infinite recursion. Similarly, recursion also needs to consider recursive exits when using template expansion.
To achieve random log output, such as

 Zz::logold (1 );     Zz::logold (1 , 2 );  Zz::logold (1 , 2 ,    Span class= "hljs-string" > '-' ,  "Today" );     int a  [4] ; Zz::logold ( "Hello" ,  "world" , 2016 ,  '-' , 3 , , 19 , a);   

The argument is not controllable, but in the recursive expansion, the last parameter is definitely the exit of recursion, as shown in the logOld function definition above. The effect of running:

However, this is a recursive implementation, the generated code is also nested, performance loss, but the reality is convenient and easy to understand.

Recently read some articles about variable parameter templates, there are some articles about the Parameter pack use of this Pack expansion .
>

Pack Expansio
A pattern followed by an ellipsis, in which the name of least one parameter pack appears at least once, is expanded int o zero or more comma-separated instantiations of the pattern, where the name of the parameter pack was replaced by each of The types from the pack, in order.

It is to provide a multi-parameter unpacking mode, the pattern must contain at least one parameter.

Based on this feature, I have designed the following code

template <typename T  >typename std::d ecay<t  > unpack (const    t  & T) {std::cout << t <<  ";    TypeName std::d ecay<t  > _ins; return  _ins;} Template <typename t , TypeName  ...  Args>void Debuglogimpl (const t  & T, const args&  ...     args) {std::cout << t <<  "; Auto _fun = [] ( ... )    {};    _fun (Unpack (args) ); Std::cout <<  \ n ' ;}  

Unpack is a schema for unpacking a parameter,unpack (args) ... Describes multiple parameters.
For example, args is a,b,c, then unpack (args) ... Equivalent to unpack (a), unpack (b), unpack (c). This form of unpacking results, I now only think of as a function parameter. All I've defined is a lambda function that takes a multi-parameter and then calls this lambda function to invoke the unpack function collection after unpacking.
But the order of function parameters in the stack is from right to left, then the first call is unpack (c), the output is "C", then No. But in c++14, we can directly

    ...);

But in the c++11, this is not possible. I also didn't find a way to call the function after unpacking in this order. In order to solve the problem of the log is not smooth, but also wrote a large section of the special template.

Template<TypeNameT>TypeName STD::d ecay<t> Unpack (Constt& t) {STD::cout<< T <<"';TypeName STD::d ecay<t> _ins;return_ins;}Template<TypeNameTTypeName... Args>voidDebuglogimpl (Constt& T,Constargs&. args) {STD::cout<< T <<"';Auto_fun = [] (...)    {}; _fun (Unpack (args) ...);STD::cout<<' \ n ';}Template<TypeNameT0>voidDebuglog (Constt0& t0) {Debuglogimpl (t0);}Template<TypeNameT0,TypeNameT1>voidDebuglog (Constt0& t0,Constt1& t1) {Debuglogimpl (t0, T1);}Template<TypeNameT0,TypeNameT1,TypeNameT2>voidDebuglog (Constt0& t0,Constt1& T1,Constt2& T2) {Debuglogimpl (t0, T2, T1);}Template<TypeNameT0,TypeNameT1,TypeNameT2,TypeNameT3>voidDebuglog (Constt0& t0,Constt1& T1,Constt2& T2,Constt3& T3) {Debuglogimpl (t0, T3, T2, T1);} ...Template<TypeNameT0,TypeNameT1,TypeNameT2,TypeNameT3,TypeNameT4,TypeNameT5,TypeNameT6,TypeNameT7,TypeNameT8,TypeNameT9>voidDebuglog (Constt0& t0,Constt1& T1,Constt2& T2,Constt3& T3,Constt4& T4,Constt5& T5,Constt6& T6,Constt7& T7,Constt8& T8,Constt9& T9) {Debuglogimpl (t0, T9, T8, T7, T6, T5, T4, T3, T2, T1);}

Adjust the parameters.

#define DEBUG_LOG(...) zz::debugLog(__VA_ARGS__)

Define a macro to unify the external caliber.

int main () {//    ZZ:: Logold(1);//    ZZ:: Logold(1,2);//    ZZ:: Logold(1,2,'-',"Today");//int a[4];//    ZZ:: Logold("Hello","World", .,'-',3,'-', +, a);Debug_log(1);Debug_log(1,2);Debug_log(1,2,3);Debug_log(1,'-',' A ',1,"Sssss");return 0;}

The results are as follows

Then there is

Tstd::decay<T>T& t){    std::cout‘ ‘;    std::decay<T> _ins;    return _ins;}

Why do you use decaythis way, if you don't have to

template <typename T>T unpack(const T& t){    std::cout‘ ‘;    return t;}

For such a "Ssssss", it will be reported

/home/zhou/work/qt_project/zzLog/main.cpp:48functionfor‘unpack(const char [6])‘     _fun(unpack(args)...);---/home/zhou/work/qt_project/zzLog/main.cpp:36function returning an array                     ^

Use decay To resolve the problem by degrading the array const char* .

Using variable template parameters to implement the log function

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.