C++11 new feature five--variable parameter template

Source: Internet
Author: User

Sometimes, we define a function, which may need to support variable-length arguments, which means that the caller can pass in any number of arguments. For example, C function printf ().

We can call it that way.

printf ("Name:%s, Number:%d" "Obama"1);  

So how does this function be implemented? In fact, the C language supports variable length parameters.

Let's give an example,

 double  Sum (int   Count,)      {va_list ap;  double  sum = 0  ;        Va_start (AP, Count);  for  (int  i = 0 ; I < count; ++i) { double  arg = Va_arg (AP, 
    
     double 
     );      Sum  += Arg;        } va_end (AP);   return   sum; }  

The above function, which accepts variable-length parameters, is used to accumulate all input parameters. This can be adjusted:

double sum = SUM (41.02.03.04.0);  

The result is 10, very good.

So what's wrong with the C language function?

1. The function itself does not know how to pass in a few parameters, such as I now pass a parameter, or pass a parameter less, then the function itself is not detected this problem. This can result in undefined errors .

2. The function itself does not know the type of arguments passed in. In the above example, what if I change the second parameter 1.0 to a string? The answer is to get an undefined error, which means you don't know what will happen.

3. For variable length parameters, we can only use the __cdecl calling convention, because only the caller knows that several parameters are passed in, then only the caller can maintain the stack balance. If it is __stdcall, then the function needs to be responsible for the stack balance, but the function itself does not know that there are several parameters, after the function call ends, there is no need to take a few parameters pop out. (Note: Some compilers such as VS, if the user wrote a __stdcall variable-length parameter function, VS will automatically convert to __cdecl, of course, this is what the compiler did)

In the C + + language, before c++11, C + + is only compatible with C, and C + + itself does not have a better alternative. In fact, for C + + such a strong type of language, C of this variable length scheme and so open a backdoor, function actually do not know what type of parameters passed in. So in C++11, a more modern support for variable-length parameters is provided, which is the variable-length template .

template Parameter Pack (Template parameter pack)

class Car;  

TypeName ... Represents a template parameter package. You can instantiate a template like this:

car<intChar

Let's look at a more specific example:

class car{};  Templateclass public car<a...>{};  BMW<intchar> car;  

In this example, BMW is a variable-parameter template that inherits from the class car. So bmw<int, char> car, when the template deduction can be considered to become car<int, char>. The credit should belong to a ...,

A... Called Package extensions (Pack extension), package extensions can be passed. such as inheritance, or directly within the parameters of the function passed. Then when the compiler is deduced, the package extension will be expanded, the above example, a ... It expands into int, char. C++11 defines several places where a package can be expanded :

1. Expressions

2. Initialize the list

3. Base class description List

4. class member Initialization list

5. Template parameter list

6. General Properties List

7. Capture List of LAMDA functions

Other places are not to be unfolded.

For the above example, what happens if we change to Bmw<int, char, int> car? Compile the time of the direct error,

Error 1 Error C2977: ' Car ': too many template arguments D:\study\consoleapplication2\variablelengthparameters\variablel ENGTHPARAMETERS.CPP27 1 Variablelengthparameters


This is because when it unfolds, a ... becomes int, char, int, maybe the base class does not have 3 template parameters at all, so the derivation is wrong. And if that's the case, what's the point of variable-length parameters? This is equal to the number of arguments each time or fixed AH. Of course not so silly, in fact c++11 can be handed back to realize the real variable length. Look at the code below.

Template<typename ... A>classbmw{}; Template<typename Head, TypeName ... Tail>classBmw PublicBmw<tail...>  {   Public: BMW () {printf ("Type:%s\n", typeID (Head). Name ()); }  Private: Head head;    }; Template<>classbmw<>{};//Boundary ConditionsBMW<int,Char,float> Car;

If we run this code, we'll see that the constructor was called 3 times. The first time you get the type is float, the second is Char, and the third time is int. This is like when the template is instantiated, the layers are expanded. This is actually the same thing. This uses the C + + template's specificity to achieve recursion, each recursive to get a type. Take a look at the object car what's inside:

You can see clearly that there are three head in the car. The head of the base class is float, the second head is Char, and the third head is int.

With this foundation, we can implement our variable-length template class, andStd::tuple is a good example. Can look at its source code, here is no longer introduced.

variable-length templates can be used not only for the definition of classes, but also for user function templates . Next, use variable-length parameters to implement a SUM function, and then contrast it with the C language version above.

Variable-length templates implement the SUM function

Look directly at the code:

Double Sum2 (T1 p, T2 ... arg)  {      double ret = p + Sum2 (arg ...);         return ret;  }     Double Sum2 ()  //  boundary condition   {      return0;  }  

In the above code, you can see the recursion very clearly.

double Ret2 = Sum2 (1.02.03.04.0);  

The calling code also gets the result 10. This process can be understood as the function of the boundary condition is executed first, then the execution of 4.0 is completed, and then the 3.0,2.0,1.0 is executed. A typical recursion.

OK, what are the benefits compared to the C language version?

Variable length template benefits

The main drawbacks of several C-language versions mentioned before:

1. The number of parameters, then for the template, in the template deduction, you already know the number of parameters, that is, at the time of compilation is determined, so that the compiler can exist to optimize the code.

2. Parameter types, the derivation of the time has been determined, the template function can know the parameter type.

3. Now that you know the number of parameters and the type of parameters when compiling, there is no limit to the calling convention.

Let's experiment with the 2nd.

int_tmain (intARGC, _tchar*argv[]) {      DoubleRet1 = Sum (4,1.0,2.0,3.0,4.0,"ABCD"); DoubleRet2 = Sum2 (1.0,2.0,3.0,4.0,"ABCD"); return 0; }  

Sum is a C language version, and the last parameter passes a string, but the SUM function cannot detect the error. The result is undefined.

Sum2 is a template function, the last parameter is also a string, at the time of compiling the error,

Error 1 Error C2111: ' + ': pointer addition requires integral Operandd:\study\consoleapplication2\variablelengthparamete RS\VARIABLELENGTHPARAMETERS.CPP29 1 Variablelengthparameters

Double cannot be added to the string, so at compile time tells us this error, we can fix it, but the C language version does not error, the code is out of control, do not know what will get results.

How, the variable length template is better than the C language variable length parameter.

So, let's use C++11 's variable-length template as much as possible.

last question, why use variable length parameters? Some people may ask, is it possible to put all the parameters in a list, and then the function to traverse the whole list, and then add it? Good point,

If all the parameter types are the same, you can do this, but what if the parameter types are different? How do you put it in a list? A strongly typed language like C + + may not be possible, indeed weakly typed languages such as Php,python, and so on, can do so. I understand that weak-type languages such as scripting languages do not require variable-length arguments, or are not important. But C + + is still needed,

With variable length template is not the problem, even if the parameter type is not the same, as long as the corresponding type has the corresponding operation, there is no problem. Of course, like the above example, if there is no overload +, then compile the error, this is not what we need?

Report:

//VariableLengthParameters.cpp:Defines the entry point for the console application. //  #include"stdafx.h"#include"stdarg.h"#include<typeinfo>DoubleSum (intcount, ...)      {va_list ap; Doublesum =0;        Va_start (AP, Count);  for(inti =0; I < count; ++i) {Doublearg = Va_arg (AP,Double); Sum+=Arg;        } va_end (AP); returnsum; } template<typename T1, TypeName ... T2>DoubleSum2 (T1 p, T2 ... arg) {DoubleRET = p +Sum2 (Arg ...); returnret; }    DoubleSum2 () {return 0; } template<typename ... A>classbmw{}; Template<typename Head, TypeName ... Tail>classBmw PublicBmw<tail...>  {   Public: BMW () {printf ("Type:%s\n", typeID (Head). Name ());  } head head;    }; Template<>classBmw<>{}; BMW<int,Char,float>car; int_tmain (intARGC, _tchar*argv[]) {      DoubleRet1 = Sum (4,1.0,2.0,3.0,4.0); DoubleRet2 = Sum2 (1.0,2.0,3.0,4.0); return 0; }  

"Turn from" http://blog.csdn.net/zj510/article/details/36633603

C++11 new feature five--variable parameter template

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.