Describes the variable-length parameter templates of C ++ 11.

Source: Internet
Author: User

Currently, the latest versions of most mainstream compilers support most of the syntax features of the C ++ 11 standard (ISO/iec14882: 2011, the new syntax features that are hard to understand may be variable-length parameter templates. The following describes the syntax feature in the C ++ 11 standard.

14.5.3 variable-length parameter template (variadic templates)

1. OneTemplate parameters(Template parameter pack) Is a template parameter that accepts zero or multiple template parameters. [Example:

Template <class... types> struct tuple {}; tuple <> t0; // types does not include any real parameter tuple <int> T1; // types contains a real parameter: inttuple <int, float> T2; // types contains two real parameters: int and floattuple <0> error; // error: 0 is not a type

-- End of example]

2. OneFunction Parameters(Function parameter pack) Is a function parameter that accepts zero or multiple function arguments. [Example:

Template <class... types> void F (types... ARGs); F (); // OK: ARGs does not include any real parameter F (1); // OK: ARGs contains a real parameter: INTF (2, 1.0 ); // OK: ARGs contains two real parameters: int and double.

-- End of example]

3. A parameter package is either a template parameter package or a function parameter package.

4. One packageExtension(Expansion) ByMode(PatternAnd a ellipsis. Package extended instances generate zero or more instances in the list. The format of the mode depends on the context where the extension occurs. Note:

Template <typename... TS> // typename... ts is the template parameter package, and Ts is the static void myprint (const char * s, TS... ARGs) // ts... ARGs is the function parameter package, and ARGs is the mode {printf (S, argS ...);}

]

Package extensions occur in the following context:

-- In a function parameter package (8.3.5), this mode is a function without ellipsis.Parameter-Declaration. Note:

Template <typename... types> void func (types... ARGs); // ARGs is the mode

]

-- In a template parameter package, this package is a package extension (14.1 ):

-- If the template parameter package isParameter-DeclarationAnd this mode has no ellipsisParameter-Declaration. Note:

Template <typename... types> // types is the mode void func (types... ARGs );

]

-- If the template parameter package hasTemplate-parameter-listOneType-ParameterAnd the mode isType-ParameterThere is no ellipsis. Note:

// The pattern of the template parameter package is classestemplate <template <typename P, typename q> class... classes> struct myastruct;

]

-- In the list of initiators (8.5); the mode isInitializer-clause.

-- InBase-specifier-list(Clause 10); mode isBase-specifier.

-- In a mem-initializer-List (12.6.2), the mode is a mem-initializer.

-- InTemplate-argument-list(14.3), the mode isTemplate-argument.

-- InDynamic-exception-Specification(15.4); the mode isType-ID.

-- InAttribute-listMedium (7.6.1); the mode isAttribute.

-- InAlignment-specifier(7.6.2); the mode has no ellipsisAlignment-specifier.

-- InCapture-list(5.1.2), the mode is a capture.

-- InSizeof... Expression (5.3.3), the pattern isIdentifier.

[Example:

Template <class... types> void F (types... rest); Template <class... types> void g (types... rest) {f (& rest ...); // "& rest... "is a package extension;" & rest "is its mode}

-- End of example]

5. The name of a parameter package appears in the package extension mode and is extended by the package. One appearance of the name of a parameter package is extended only by the package extension that is the most internal closed. One package extension mode should name one or more parameter packages, and a nested package extension will not expand them; such parameters are called in the ModeNot extendedParameter package. All parameter packages extended by a package extension should have the same number of specified real parameters. One appearance of a name of a parameter package that is not extended is undesirable. [Example:

Template <typename...> struct tuple {}; template <typename T1, typename T2> struct pair {}; template <class... args1> struct zip {template <class... args2> struct with {typedef tuple <pair <args1, args2>...> type ;}; // Translator's note: Here is the extension of pair <args1, args2>}; // T1 is tuple <pair <short, unsignd short>, pair <int, unsigned> typedef zip <short, int >:: with <unsigned short, unsigned >:: Type T1; // error: specify different numbers of real parameters typedef zip <short >:: with <unsigned short, unsigned >:: Type T2; Template <typename... ARGs> void F (ARGs... ARGs) {} template <class... ARGs> void g (ARGs... ARGs) {// OK: ARGs is extended by ARGs in the function parameter package F (const_cast <const ARGs *> (& ARGs )...); // OK: "ARGs" and "ARGs" are extended F (5 ...); // error: the mode does not contain any form parameter package F (ARGs); // error: the form parameter package "ARGs" is not extended F (H (ARGs ...) + ARGs ...); // OK: the first "ARGs" is extended within h, and the second "ARGs" is extended within f}

-- End of example]

6. A package extension instance is notSizeof...Expression to generate a list of E1, E2, E3,..., en. Here, n is the number of elements in the package extension parameter. Each EI is generated by instantiating this mode and replacing each package extension parameter with its I-th element. All EI elements in the closed list. [Note: the diversity of the List varies according to the context:Expression-list,Base-specifier-list,Template-argument-listAnd so on. -- Note end: WHEN n is zero, the extended instance generates an empty list. Such an instance does not change the syntax interpretation of the closed structure, or even causes the singularity of the syntax when the entire list is ignored. [Example:

Template <class... t> struct X: t... {// Add x (t... ARGs) {}}; template <class... t> void F (t... values) {x <t...> X (values ...);} template void F <> (); // OK: x <> no base class; X is a variable of Type X <> initialized by a value. // The translator adds: int main () {struct y {}; struct Z {}; F <> (); // use template void F <> (); x <> X (); // use template <class... t> void F (t... values); // its internal use of x <y, z> X (Y (), Z (); // while x <y, z> is defined: struct X: y, z {x (Y arg1, Z arg2) {}}; f (y (), Z ());}

-- End of example]

7. OneSizeof...The expression instance (5.3.3) generates an integer constant that contains the number of elements in the expanded parameter package.

The above is the description of the variable-length template parameters in the C ++ 11 standard. Below I will provide some code examples for further description to help you better understand, especially the package extension mechanism.

// ================================================ ==================================================================== // Name: cpptest. CPP // Author: zenny Chen // version: // copyright: Your copyright notice // Description: Hello world in C ++, ANSI-style // ========================================== ========================================================== = # include <iostream> # include <typeinfo> using namespace STD; # include <stdio. h> # include <stdarg. h> struct mytes T; // common variable-length parameter of the C function static void mycprint (const char * s ,...) {char strbuffer [1024]; va_list AP; va_start (AP, S); vsprintf (strbuffer, S, AP); va_end (AP); printf (strbuffer );} template <typename... TS> // typename... ts is the template parameter package, and Ts is the static int myprint (const char * s, TS... ARGs) // ts... ARGs is the function parameter package, and ARGs is the mode {return printf (S, argS ...);} template <typename... TS> // template parameter pack static void dummy ITER (TS... ARGs) // function parameter pack {} template <typename T> static t show (T, int N) {cout <"the value is: "<t <", and n = "<n <Endl; return t;} template <typename... TS> static void func (TS... ARGs) {// here, show (ARGs, sizeof... (ARGs) is the mode, so show (ARGs, sizeof... (ARGs ))... extended // The type of each ARGs instance is the actual parameter type of the corresponding ts template // here, the show (T, INT) function must return the T type, not the void, because of void and TS... type cannot match dummyiter (show (ARG S, sizeof... (ARGs)...) ;}// note the differences between the following two function call methods! Template <typename... types> static void Foo (types... ARGs) {// call the extension myprint ("the type is: % s \ n", typeid (ARGs) for dummyiter ). name () dummyiter (myprint ("the type is: % s \ n", typeid (ARGs ). name ())...); puts ("=============="); // call the extension ARGs dummyiter (myprint ("the first value is: % d, second is: % s, third is: % F \ n ", argS ...));} // further describe template <typename... types> struct variadicstru CT: types... {}; template <typename... types> static void constructstruct (void) {variadicstruct <types...> ();} template void constructstruct <> (void); // OK: variadicstruct <> no base class template <typename... types> static void F (types... ARGs) {printf ("the sample values are: % F, % F \ n", argS ...);} // The ftemplate <> void F <> () {cout <"no arguments! "<Endl;} template <typename T1, typename T2> static auto H (T1 T1, T2 T2)-> decltype (T1 * t2) {return T1 * t2 ;} template <typename... types> static void g (types... ARGs) {// here, after calling g (10, 0.1) in the main function, it will be expanded to: // F (H (10, 0.1) + 10, H (10, 0.1) + 0.1); // here there are two layers of package expansion. For f (), the mode is H (ARGs ...) + ARGs // then for H (), the pattern is ARGs //. Therefore, the rightmost ellipsis is actually for the whole (H (ARGs ...) + ARGs) for extension // It is equivalent to: F (h (ARGs ...) + ARGs )...); F (H (ARGs ...) + ARGs ...);} extern "C" Void cpptest (void) {mycprint ("This is C print: % d, % s \ n", 1, "Hello, world! "); Myprint (" this is my print: % d, % s \ n ",-1," Hello, world! "); Func (-100, 0.5); puts (" "); Foo (3," hello ", 0.25 ); // further describe puts ("\ n"); struct a {}; struct B {}; constructstruct <, b> (); // within this function, variadicstruct <A, B> constructstruct <> (); // within this function, variadicstruct <>, it has no base class G (10, 0.1); G <> ();}

 

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.