C ++ function template implementation and optimization abstract operation

xiaoxiao2021-03-06  15

Summary: This article introduces the concept, use of function templates, how to create function templates and function templates ...

When creating a function of the abstract operation, such as copy, reverse, and sort, you must define multiple versions to handle each data type. Take the max () function as an example, it returns a larger in the two parameters:

Double Max (Double First, Double Second); Complex Max (Complex First, Complex Second); Date Max (Date First, Date SECOND);

// .. Other versions of this function

Although this function is the same for different data types, the programmer must define a separate version for each data type:

Double Max (Double First, Double Second) {Return First> Second? First: Second;}

Complex Max (Complex First, Complex Second {RETURN FIRST> Second? first: second;

Date Max (Date First, Date Second) {Return First> Second? First: Second;}

This is not only repeated labor, it is easy to make mistakes, but also brings great maintenance and debugging efforts. Worse, even if you don't use a version in the program, its code still adds the size of the executable, most compilers will not remove uncounted functions from the executable.

Using normal functions to implement abstract operations will force you to define multiple function instances, causing unmisting maintenance and debugging overhead. The solution is to use the function template instead of the normal function.

Use function template

The function template solves all of the above problems. The type is independent and automatically instantiated only when needed. This article will show how to define a function template for abstract general operation, demonstrating its use, and discussing optimization techniques.

Step 1: Definition

The declaration of the function template is the parameters and prototypes follow one or more templates after the keyword template. Compared to normal functions, it is usually declared in a conversion unit, and in another unit, you can define templates in a header file. E.g:

// file max.h # ifndef max_included # define max_includedtemplate T max (t T1, t2) {RETURN (T1> T2)? T1: T2;} # ENDIF

Definition T as a template parameter, or a placeholder, when instantimizing max (), it will replace the specific data type. MAX is a function name, T1 and T2 are their parameters, and the type of return value is T. You can use this max () like it is using a normal function. The compiler automatically generates the corresponding template transit according to the data type used, or is an example:

INT n = 10, m = 16; int highest = max (n, m); // Generate int version

Std :: Complex C1, C2; / / .. Give C1, C2 assignment std :: complex higher = max (C1, C2); // Complex version

Step 2: Improvement Design

The implementation of the above MAX () has some rustic-parameters T1 and T2 are delivered by values. For built-in data types like int, Float, is not a problem. However, for user-defined data types such as std :: complex and std :: Sting, pass the parameters more efficient by reference. In addition, because max () will think that its parameters will not be changed, we should declare T1 and T2 as const (constants). Below is an improved version of Max (): Template T Max (Const T & T1, Const T & T & T & T & T & T & T & T & T & T2) {RETURN (T1> T2)? T1: T2;}

Additional performance issues

Fortunately, standard template libraries or STLs have defined a algorithm called std :: max () in . Therefore, you don't have to reinvent. Let us consider more realistic examples, namely byte sorting. It is well known that the TCP / IP protocol is required to use a BIG Endian byte order when transmitting a multi-word value. Therefore, the BIG Endian byte order is also known as a network byte order. If the destination host uses the Little Endian order, you must convert all the paragraph values ​​over to the Little Endian order. Similarly, the host must convert them into a network byte order before transmitting a multi-byte value through TCP / IP. Your Socket library four functions, which are responsible for the transformation between host byte and network byte order:

Unsigned int htonl; unsigned short htons (unsigned short hostshort); unsigned int NTOHL; UNSIGNED SHORT NTOHS (Unsigned Short Netsh);

These functions achieve the same operation: the byte of the multi-word value. The only difference is directionality and the size of the parameters. Ideal for template. Use a template function to replace these four functions, we can define a smart template that handles all these four situations and more situations:

Template T byte_Reverse (T VAL);

In order to determine the actual type of T, we use the SizeOf operator. In addition, we also use STL's Std :: Reverse algorithm to reverse the byte:

Template t byte_reverse (t val) {// Transforms VAL as byte stream Unsigned char * p = reinterpret_cast ; std :: Reverse (p, p sizeof (val)); Return Val;

Instructions

BYTE_REVERSE () template processing is fully applicable to all situations. Moreover, it can also be flexibly applied to other originals (eg 64-bit and 128 bits) that do not have to modify any code.

INT main () {int N = 1; short k = 1; __INT64 J = 2, I; int m = byte_reverse (n); // reverse int = byte_reverse (k); // Reverse Short k = byte_reverse K); // un-revrse K i = byte_reverse (j); // reverse __int64} Note: Improper use of templates will affect the size of the .exe file, that is, common code edema issues.

转载请注明原文地址:https://www.9cbs.com/read-45955.html

New Post(0)