Use of templates in C + +

Source: Internet
Author: User

Template refers to the function template and class template in C + + programming language, which is a parameterized type mechanism. Templates are an integral part of C + + generic programming.

C + + templates enable define a family of functions or classes that can operate on different types of information.

A template is a tool for implementing a code reuse mechanism that implements type parameterization, which defines a type as a parameter, enabling true code reusability.

Template declaration and definition: the template definition starts with the keyword templates, followed by the template parameter list (template parameter list), which is a listing of one or more template parameters enclosed in angle brackets. The formal parameters are separated by commas. A template parameter can be a type parameter that represents a type (type parameter), or it can be a non-type parameter (non-type parameter) that represents a constant expression. A non-type parameter is followed by a type descriptor declaration. Type parameters are declared after the keyword class or typename. The template parameter can give the default value, which is arguments for parameters.

The template's non-type parameters (templates non-type parameter) are allowed in the following form: (1), integer or enum type, (2), pointer to object or function pointer, (3), reference to object or function reference, (4), member pointer.

A template's non-type parameter is declared as an array or function, and will be converted to a pointer or function pointer. The template's non-type parameter is allowed with const or volatile qualification (whereas the template's type parameter is not allowed to be qualified with const or volatile). The template's non-type parameters are not allowed to be declared as floating-point, Class-type, void-type.

Template parameters for templates: Template parameters for class templates are allowed to be another class template, which is called template template parameters for templates (template parameter), and also translated as templates parameter templates. Template parameters for templates are not allowed for function templates.

default value for template parameter: The template parameters can give default values (arguments for parameters). If a template parameter gives the default value, then the template parameters declared later in the template parameter list should give the default value.

The default values of the template parameters given by each declaration of a template can accumulate its effect. The scope of the template parameter is from where it is declared to the end of the definition of the template. You can therefore use a template parameter as part of or a default value for other template parameters declared later.

Use of templates: When you use a template, you can explicitly give a list of template arguments enclosed in angle brackets, followed by the template name (argument list). Template arguments to template functions or classes, or not explicit template arguments, are deduced by the compiler based on the context of the function call, which is called template argument derivation.

If the template parameter uses its default value, it can be ignored in the template argument list. If all the template parameters use the default values, the template argument list is empty, but you still have to write the pair of angle brackets.

For template arguments as a type, it is not allowed to be a local type, a non-linked type (type with no linkage), a nameless type (unnamed type), or a composite type that includes these three scenarios. But c++11 to allow the local type as a template argument.

Template nesting: Member templates, for template member functions in classes, nested member class templates, can be defined inside or outside the enclosing class. When template member functions, nested class templates are defined outside their enclosing class, they must begin with template parameters for the enclosing class template (if they are also template classes) and member templates. The C + + standard stipulates that if the outer class template is not an exception, the member template inside cannot be instantiated.

Dependent names and TypeName keywords: a template that relies on a template parameter (templates parameter) is called the name of the dependent name (dependent name). When a dependent name is nested inside a class, it is called a nested dependent name (nested dependent name). A name that does not depend on any template parameter, called the Non-dependent name (non-dependent name).

When the compiler processes a template definition, it may not be certain whether the dependent name represents a type, is a member of a nested class, or is a static member of a class. The C + + standard stipulates that if the parser encounters a nested dependency name in a template, it assumes that the name is not a type unless the name is explicitly decorated with the TypeName keyword.

The TypeName keyword has two uses: (1), a common template parameter list in the template definition, indicating that a template argument is a type parameter. Equivalent to using class. (2), when using a nested dependency type name defined within a template class, explicitly indicates that the name is a type name. Otherwise, the name will be interpreted as the static member name of the template class. C++11, this use can also appear outside the template, although the TypeName keyword is not necessary at this time.

In the following cases, the predecessor Modifier typename keyword is not required for nested dependency type names: (1), base class identifier in the base class list declared by the derived class, (2), base class identifier in the member initialization list, (3), type identifier starting with a keyword such as class, struct, enum, and so on. Because their context already indicates that these identifiers are the names of the types.

The template keyword has two uses: (1), common at the beginning of the template definition, and (2), template class internal definition of templates member functions or nested member template classes. In a template, when you reference such a template member function or a nested member template class, you can use the::(scope resolution) operator,. The template keyword is used after the (Access member by object) operator, the (Access member by pointer) operator, followed by the name of a member function or a nested member template class name, which causes the subsequent left angle bracket < to be interpreted as the start of the template argument list. Instead of the less than number operator. C++11, this use can also appear outside the template, although this time the template keyword is not necessary.

Template instantiation instantiation: Refers to the specific instance source code that generates a function template or class template at compile or link time. ISO C + + defines two template instantiation methods: implicit instantiation (the instantiation Code of the template is automatically inserted before the current unit of code when the instantiated template is used), explicit instantiation (Direct declaration of template instantiation). In the different implementations of the C + + language, template compilation mode (the method of template initialization) can be broadly divided into three types:

(1), Borland Model (contains template compilation mode): The compiler generates all the template instances encountered in each compilation unit, and is stored in the corresponding target file; The linker merges the same template instance to generate the executable file. For each template instantiation, the template definition is visible, and the declaration and definition of the template is placed in the same. h file. The advantage of this approach is that the linker only needs to process the target file; The disadvantage of this approach is that the template instance is compiled repeatedly, the compilation time is extended, and the linker cannot be used without the system's linker.

(2), cfront/query Model (separation (separation) template compilation mode): AT-T company's C + + compiler Cfront to solve the problem of template instantiation, added a template warehouse to hold the template instance code and can be automatically maintained. When a target file is generated, the compiler stores the template definitions that are encountered with the currently generated template instances in the template repository. When linking, the linker's wrapper (wrapper) first calls the compiler to generate all the template instances that are required and are not in the template repository. The advantage of this method is that the compilation speed is optimized, and the system's linker can be used directly; The disadvantage of this method is that the complexity is greatly increased and error-prone. Source programs that use this model typically place template declarations with non-inline template members in. h files and template definition files, which are compiled separately.

(3), mixed (iterative) Model: g++ is currently based on the Borland model to complete the template instantiation. G++ will implement the template instantiation of the hybrid model in the future, that is, the compiler stores the template definition in the compilation unit and the currently implemented template instance that is encountered in the corresponding target file; The linker's wrapper (wrapper) invokes the compiler to generate the template instance that is not currently instantiated. ; The linker merges all the same template instances. Source programs that use this model typically place template declarations with non-inline template members in. h files and template definition files, which are compiled separately.

The ISO C + + standard specifies that if the template is implicitly instantiated, the template's member functions are instantiated until the reference, and if the template is explicitly instantiated, all members of the template are instantiated immediately, so that the declaration and definition of the template should be visible here. Also, when other program text files use this template instance, the compiler option suppresses the template from being implicitly instantiated, or the definition portion of the template is not visible, or a statement using the Template<> type Fun_name (Type list) declares the template's specificity but does not instantiate it.

About templating instantiation (template instantiation):

(1), the specific instance source code that generates a function template or class template at compile or link time, that is, replace the template type parameter with the actual parameter type when using the template (there are also non-type parameters and template-type parameters);

(2), implicit instantiation (implicit instantiation): When the instantiated template is used to automatically insert the template's instantiation code before the current code unit, the template's member function is instantiated until the reference;

(3), explicit instantiation (explicit instantiation): Direct declaration of template instantiation, all members of the template are immediately instantiated;

(4), instantiation is also an exception, known as an instantiation of the special case (instantiated (or generated) specialization).

When implicitly instantiated, members are instantiated only if they are referenced, which is called deferred instantiation (lazy instantiation).

Template instantiation is the generation of specific classes or functions (instances) that take a particular combination of template parameters. For example, the compiler generates a class that takes array<int>, and another class that takes array<double>. You can define these new classes by replacing template parameters in template class definitions with template parameters.

About the compilation and linking of templates:

(1), including template compilation mode: The compiler generates all the template instances encountered in each compilation unit and is stored in the corresponding target file; The linker merges the equivalent template instance, generates the executable file, requires that the template definition is visible when instantiated, and cannot use the system linker;

(2), separate template compilation mode (using the Export keyword): Do not repeat the generation of template instances, compiler design requirements are high, you can use the system linker;

(3), including the compilation mode is the mainstream, c++11 has deprecated the Export keyword (introducing extern new usage of the template), generally put the full implementation code of the template in the same header file and in the use of templates in the place with # include headers, to prevent the occurrence of inconsistent instances.

About the use of the template, typename, this keyword:

(1), dependent on the template parameters (templates parameter, formal parameters, the name of the English argument) is called the dependent name (dependent name), the C + + standard specifies that if the parser encounters a nested dependency name in a template, It assumes that the name is not a type unless the name is explicitly decorated with the TypeName keyword;

(2), similar to the previous TypeName usage, the template is used to indicate that a nested type or function is a stencil;

(3), this is used to specify the lookup of a member in a base class (when the base class is a class template instance that relies on template parameters, because the instantiation is always deferred, the name that does not depend on the template parameter is not found in the base class).

C++11 new features about templates:

(1), ">>" automatically recognize the correct semantics according to the context;

(2), function template parameter default value;

(3), variable length template parameters (extended sizeof ... () Gets the number of parameters);

(4), template alias (extension using keyword);

(5), external template instances (expand the extern keyword), discard export template.

Function templates: Templates (Templates) allow us to generate general-purpose functions that accept parameters of any data type, return any type of value, and do not require a function overload on all possible data types. This is to some extent realized the role of macro. Template functions can also be declared in advance, but you need to bring a template header when declaring.

A function template describes a set of related functions that are distinguished only by the type of the parameter or return value. For function templates, the compiler does not support expressions for non-type template parameters in a function argument list.

class template (class templates): Allows a class to have a member based on a common type, without having to define a specific data type when the class is generated

Template Specialization (special case, templatespecialization): defined by the following format:

Template<> class Class_name <type>

This specialization itself is part of the template definition, so we must write template <> at the beginning of the definition. And because it is really a specific type of special definition, the common data type cannot be used here, so the first pair of angle brackets <> must be empty. After the class name, we must write the specific data type used in this specialization in angle brackets <>.

When we specialize a data type for a template, you must also redefine the specialization implementation of all members of the class. The reason for this is that specialization does not inherit any one member of the generic template.

The so-called template exception is the general practice of some or some of the circumstances to do a separate special implementation, the simplest case is to specify a specific value for each template parameter, which becomes a complete exception (full specialization), in addition, you can limit the template parameters in a range to value or satisfy a certain relationship, etc. This is called partial exception (partial specialization), with the concept of a mathematical set, the usual template parameters of all the desirable combinations of values to form the complete set U, a complete exception to an element in U specifically defined, a partial exception to a true subset of U specifically defined.

About Template Exceptions:

(1), before defining the template special case must already have the template of the usual (primary template) declaration;

(2), template Special case does not require certain and general practice have the same interface, but in order to facilitate the use (experience the semantics of special cases) are generally the same;

(3), matching rules, when template instantiation, if there are template orders, special cases add up more than one template version can match, then according to the following rules: to version AB, if a template parameter collection is a true subset of B, then first match a, if the set of template parameters of AB is a "cross" relationship (AB) intersection is NOT NULL, And does not contain a relationship), a compilation error occurs, and for a function template, a function overload resolution (overload resolution) rule is combined with the above rule and first matches the non-template function.

From the compiler's point of view, a template differs from a general function or class. They are compiled when needed (compiled on demand), which means that the code for a template is not compiled until it needs to generate an object (instantiation). When instantiation is required, the compiler generates a special function based on the template for a particular invocation data type.

The test code is as follows:

TEMPLATE.HPP:

#ifndef fbc_messy_test_template_hpp_#define fbc_messy_test_template_hpp_#include <vector>//Reference:https ://zh.wikipedia.org/wiki/%e6%a8%a1%e6%9d%bf_ (C%2B%2B)//function template, this function automatically generates code for the corresponding parameter type at compile time without explicitly declaring the template <typename T >inline Const t& Maximum (const t& x, const t& y) {if (Y > x) {return y;} Else{return x;}} Class templates template <typename ty>class comptr{protected:ty* m_ptr;public:comptr () {m_ptr = NULL;} COMPTR (const comptr& RHS) {m_ptr = NULL; Setcomptr (rhs.m_ptr);} COMPTR (ty* p) {m_ptr = NULL; Setcomptr (P);} ~comptr () {Release ();} Const comptr& operator= (const comptr& RHS) {setcomptr (rhs.m_ptr); return *this;} ty* operator= (ty* p) {setcomptr (P); return p;} Operator ty* () {return m_ptr;} ty* operator-> () {return m_ptr;} Operator ty** () {Release (); return &m_ptr;} Operator void** () {Release (); return (void**) &m_ptr;} BOOL IsEmpty () {return (m_ptr = = NULL);} void Setcomptr (ty* p) {Release (); m_ptr = P;if (m_ptr) {m_ptr->addref ();}} void Release () {if (m_PTR) {m_ptr->release (); m_ptr = null;}}};/ /Template Nesting: member Templates template <typename c> class myc{public:template <typename s> C foo (s s);};/ /downstream you need to give a list of template parameters for the outer class and the inner nested class: Template<typename c> template <typename s> C Myc<c>::foo (s s) {C Var;return var;} reference:http://www.tutorialspoint.com/cplusplus/cpp_templates.htm//function Templatetemplate <typename T >inline T const& Max (t const& a, T const& b) {return a < b? b:a;} Class Templatetemplate <class t>class Stack {private:std::vector<t> elems;//elements public:void push (T C onst&); push element void pop (); Pop element T top () const; Return top element bool Empty () const{//return True if Empty.return elems.empty ();}}; Template <class t>void stack<t>::p ush (T const& elem) {//Append copy of passed element Elems.push_back (ele m);} Template <class t>void Stack<t>::p op () {if (Elems.empty ()) {throw fprintf (stderr, "STACK&LT;&GT;::p op (): Empty stack\n");} Remove last element elems.pop_back (); Template <class t>t stack<t>::top () const{if (Elems.empty ()) {throw fprintf (stderr, "Stack<>::top (): Empty stack\n ");} Return copy of last element return Elems.back ();} reference:http://www.prglab.com/cms/pages/c-tutorial/advanced-concepts/templates.php//template Specialization (exceptions, templates Specialization) template <class t> class pair {private:t value1, Value2;public:pair (t first, T second) {value1 = First ; value2 = Second;} T module () {return 0;}}; Template <>class pair <int> {private:int value1, value2;public:pair (int first, int second) {value1 = First;val Ue2 = Second;} int module () {return value1% value2;}}; Template <class t> struct printtype {};template<> struct printtype <int> {const std::string type () {Retu RN "int type";}}; template<> struct Printtype <float> {const std::string type () {return ' float type ';}}; template<> struct Printtype <std::string> {const std::string type (){return "string type";}}; void Test_template1 (); void Test_template2 (); void Test_template3 (); void Test_template4 (); void Test_template5 (); endif//Fbc_messy_test_template_hpp_
Template.cpp:

#include <iostream> #include <string> #include <stdexcept> #include "template.hpp" void Test_  Template1 () {int a = 3, b = 7;float x = 3.0, y = 7.0;//calling template functionstd::cout << maximum<int> (A, B) << Std::endl; Output 7std::cout << maximum (A, b) << Std::endl; Automatic supplemental type declaration, output 7std::cout << maximum<double> (x, y) << Std::endl; Output 7}void Test_template2 () {int i = 39;int j = 20;std::cout << "Max (i, J):" << Max (i, J) << Std::endl; Double F1 = 13.5;double F2 = 20.7;std::cout << max (F1, F2): << max (F1, F2) << std::endl;std::string s 1 = "Hello"; std::string s2 = "World"; Std::cout << "Max (S1, S2):" << max (S1, S2) << Std::endl;}  void Test_template3 () {try {stack<int> intstack;    Stack of ints stack<std::string> stringstack; Stack of strings//manipulate int stack intstack.push (7); Std::cout << intstack.top () << std::endl;//Manip Ulate String stack stringstack.push ("Hello"); std::cout << stringstack.top () << std::endl;stringstack.pop ();// Stringstack.pop ();} catch (Std::exception const& ex) {Std::cerr << "exception:" << ex.what () << Std::endl;return;}} void Test_template4 () {pair <int> myints (+);p air <float> myfloats (100.0, 75.0); Std::cout << Myints.module () << std::endl;std::cout << myfloats.module () << Std::endl;} void Test_template5 () {printtype<int> type_int;std::cout << type_int.type () <<std::endl; Printtype<float> type_float;std::cout << type_float.type () << Std::endl; Printtype<std::string> type_string;std::cout << type_string.type () << Std::endl;}
Main references:

1. Https://zh.wikipedia.org/wiki/%E6%A8%A1%E6%9D%BF_ (C%2B%2B)

2. http://blog.jobbole.com/83461/

3. https://docs.oracle.com/cd/E19205-01/820-1214/bkaew/index.html


GitHub: https://github.com/fengbingchun/Messy_Test

Use of templates in C + +

Related Article

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.