C + + Advanced article (i)--Template (templates) __c++

Source: Internet
Author: User
Tags prototype definition

Template (templates) is a new concept introduced in the ansi-c++ standard. If you use a C + + compiler that does not conform to this standard, you probably won't be able to use the template.

functions Template ( function templates)

Templates allow us to generate generic functions that can accept parameters of any data type and return any type of value without the need for functional overloading of all possible data types. This realizes the function of the macro (macro) to some extent. Their prototype definition can be any of the following two types:

Template <class identifier> function_declaration;
Template <typename identifier> function_declaration;

The difference between the two prototypes defined above is the use of the keyword class or typename. They are actually completely equivalent, because both expressions have exactly the same meaning as execution.

For example, to generate a template that returns the larger of two objects, we can write this:

Template <class generictype>

GenericType Getmax (GenericType A, GenericType b) {return (A>B?A:B);}

In the first line of the statement, we have generated a generic data type template called GenericType. So in the function that follows it, GenericType becomes a valid data type that is used to define two parameters A and B and is used as the return value type of the function Getmax.

GenericType still does not represent any specific data type; When a function getmax is invoked, we can invoke it with any valid data type. This data type will be used as pattern in place of the generictype appearing in the function. The way to invoke a template with a type pattern is as follows:

function <type> (parameters);

For example, to call Getmax to compare integers of two int types can be written like this:

int x,y;
Getmax <int> (x,y);

As a result, the Getmax call is as if all generictype appear in place of int instead.

Here is an example:

function template

#include <iostream.h>

Template <class t> t Getmax (t A, T b) {

T result;

result = (a>b)? A:B;

return (result);

}

int main () {

int i=5, j=6, K;

Long l=10, m=5, N;

K=getmax (I,J);

N=getmax (L,M);

cout << k << Endl;

cout << n << Endl;

return 0;
}

6
10

(In this example, we name the generic data type T instead of GenericType, because T is shorter, and it is one of the more generic indications of the template, although it is possible to use any valid identifier.) )

In the example above, we used two parameter types for the same function Getmax (): int and long, but only one implementation of a function, that is, we wrote a template for a function that we called with two different patterns.

As you see, in our template function Getmax (), type T can be used to declare new objects

T result;

Result is an object of type T, like A and B, that is, they are all of the same type, which is the type that is written in the angle bracket <> when we call the template function.

In this particular example, the generic type T is used as the parameter of the function Getmax, and the compiler can automatically detect the incoming data type without requiring a description of <int> or <LONG>, so we can also write this example:

int i,j;
Getmax (I,J);

Since I and j are all int types, the compiler automatically assumes that we want the function to be called by Int. This implied approach is more useful and produces the same result:

function Template II

#include <iostream.h>

Template <class t> t Getmax (t A, T b) {

return (A>B?A:B);

}

int main () {

int i=5, j=6, K;

Long l=10, m=5, N;

K=getmax (I,J);

N=getmax (L,M);

cout << k << Endl;

cout << n << Endl;

return 0;

}

6
10

Notice how we call the template function Getmax () in this example's main () without specifying the specific data type in parentheses <>. The compiler automatically determines what data type is required for each call.

Since our template function includes only one data type (class T), and its two arguments are of the same type, we cannot invoke it with two different types of arguments: int i;
Long L;
K = Getmax (i,l);

The above call is not correct, because our function waits for two parameters of the same type.

We can also make the template function accept two or more types of data, such as:

Template <class t>

T Getmin (t A, U b) {return (A<B?A:B);}

In this example, our template function Getmin () accepts two different types of arguments and returns an object of the same type as the first argument. In this definition, we can call the function like this: int i,j;
Long L;
i = Getmin <int, long> (j,l);

Or, simply use the

i = Getmin (j,l);

Although J and L are different types.

class Template (classes templates)

We can also define class templates, so that a class can have members based on a common type without having to define a specific data type when the class is generated, for example:

Template <class t>

Class Pair {

T values [2];

Public

Pair (T, T second) {

Values[0]=first;

Values[1]=second;

}

};

The class we defined above can be used to store two elements of any type. For example, if we want to define an object of this class to store two integer data 115 and 36, we can write this:

Pair<int> MyObject (115, 36);

We can also use this class to generate another object to store any other type of data, such as:

Pair<float> myfloats (3.0, 2.18);

In the example above, the only member function of a class has been inline defined. If we want to define a member function of it outside of the class, we must add template to the front of each function. >.

Class templates

#include <iostream.h>

Template <class T> class Pair {
T value1, value2;
Public
Pair (T, T second) {

Value1=first;

Value2=second;

}

T Getmax ();

};

Template <class t>

T Pair::getmax () {

T retval;

retval = value1>value2? Value1:value2;

return retval;

}

int main () {

Pair MyObject (100, 75);

cout << Myobject.getmax ();

return 0;

}

100

Notice how the member function Getmax begins to be defined:

Template <class t>
T Pair::getmax ()

All places where T is written are required, and each time you define a member function of a template class you need to follow a similar format (the second T represents the type of function return value, which may vary depending on the requirement).

Template Specialization (Template specialization)

The specialization of a template is that the template has a specific implementation when pattern has a certain type in the template. For example, suppose that our class template pair contains a function that takes a modulus calculation (module operation), and we want this function to work only when the data stored in the object is an int, and we need this function to always return 0. This can be done using the following code:

Template Specialization

#include <iostream.h>

Template <class T> class Pair {

T value1, value2;

Public

Pair (T, T second) {

Value1=first;

Value2=second;

}

T module () {return 0;}

};

Template <>

Class pair <int> {

int value1, value2;

Public

Pair (int-A, int second) {

Value1=first;

Value2=second;

}

int module ();

};

Template <>

int Pair<int>::module () {

return value1%value2;

}

int main () {

Pair <int> myints (100,75);

Pair <float> myfloats (100.0,75.0);

cout << myints.module () << ' \ n ';

cout << myfloats.module () << ' \ n ';

return 0;

}

25
0

As you can see from the above code, template specialization is defined by the following format:

Template <> class Class_name <type>

This specialization itself is also part of the template definition, so we must write template <> at the beginning of the definition. And because it does have a special definition for a specific type, the generic data type is not available 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 bracket <>.

When we specialize a data type of a template, you must also redefine the specialization implementation of all members of the class (if you look closely at the example above, you will find that we have to include its own constructor constructor in the definition of specialization, although it is the same as the constructor in a generic template). The reason for this is that specialization does not inherit any of the members of a generic template.

parameter values for the template (Parameter values for templates)

In addition to the template parameters, which represent a common type in front of the keyword class or typename, function templates and class templates can also contain other parameters that are not representative of a type, such as a constant, which is usually the base data type. For example, the following example defines a class template that is used to store an array:

Array template

#include <iostream.h>

Template <class T, int n>

Class Array {

T memblock [N];

Public

void Setmember (int x, T value);

T getmember (int x);

};

Template <class T, int n>

void Array<t,n>::setmember (int x, T value) {

Memblock[x]=value;

}

Template <class T, int n>

T array<t,n>::getmember (int x) {

return memblock[x];

}

int main () {

Array <int,5> myints;

Array <float,5> myfloats;

Myints.setmember (0,100);

Myfloats.setmember (3,3.1416);

cout << myints.getmember (0) << ' \ n ';

cout << Myfloats.getmember (3) << ' \ n ';

return 0;

}

100
3.1416

We can also set a default value for the template parameter, just like setting the default value for the function parameter.

Here are some examples of template definitions:

Template <class t>//most commonly used: a class parameter.

Template <class T, class u>//two class parameters.

Template <class T, int n>//One class and an integer.

Template <class T = char>//has a default value.

Template <int tfunc (int) >//parameter is a function.

templates and multiple file engineering (templates and Multiple-file projects)

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

When the project becomes more and more large, the program code is usually split into multiple source program files. In this case, the usual interface (interface) and implementation (implementation) are separate. Using a function library as an example, the interface usually includes the prototype definition of all functions that can be invoked. They are usually defined in header files with an. h extension (header file), whereas implementations (function definitions) are in separate C + + code files.

A template such as a macro (macro-like) feature has certain limitations on multiple file engineering: the implementation (definition) of a function or class template must be declared in the same file as the prototype. That is, we can no longer store the interface (interface) in a separate header file, but must place the interface and implementation in the same file that uses the template.

Back to the example of the function library, if we want to build a library of function templates, we can no longer use header files (. h), instead we should generate a template file (template file), where the interface and implementation of the function template are placed in this file (this file does not have an idiomatic extension. In addition to not using the. h extension or without any extension. It is not a link error (linkage errors) to include template files with both declarations and implementations multiple times in a project, because they are compiled only when needed, and the compiler for the compatible template should have taken this into account and will not generate duplicate code.

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.