A function overload has the same function name but the number or type of arguments is different so that the corresponding method is invoked depending on the number of parameters and the type of parameter.
we found that the function overload only solves the problem of function naming, but the function body, although we still have to write repeatedly, in order to solve this problem C + + has a function template.
definition of function Template:
The template provides a mechanism by which we can preserve the semantics of function definitions and function calls (encapsulate a piece of code in a program location to ensure that the argument is only evaluated once before the function call) without bypassing the strong type check of C + + like the macro scenario.
Keyword template always precedes the definition and declaration of a template. The keyword is followed by a comma-delimited table of template parameters, which is enclosed in angle brackets <>. The list is a template parameter table and cannot be empty. A template parameter can be a template type parameter (template type parameter), it represents a type, or it can be a template untyped parameter (template Nontype parameter), which represents a constant expression.
The template type parameter is composed of a keyword class or typename followed by an identifier. In the template parameter table of a function, these two keywords have the same meaning. They indicate that the following parameter names represent a potential built-in or user-defined type. The template parameter name is chosen by the programmer, and in this case we use type to name the template parameter of min (). But it can actually be any name. Such as:
Template <class glorp>
Glorp min (Glorp A, Glorp b)
{
Return a < b? A:B;
}
When you call a template function, you first replace the type of the template with the user-defined type, followed by the value.
When a template is instantiated, the actual built-in or user-defined type replaces the template's type parameters.
Non-type parameters consist of a common parameter declaration. A template non-type parameter indicates that the parameter name represents a potential value, which represents a constant in the template definition. For example, size is a template-not-type parameter that represents the length of an array that arr points to.
Template <class Type, int size>
Type min (Type (&arr) [size]);
When the function template min () is instantiated, the value of size is replaced by a constant value known at compile time.
After a function definition or declaration is followed by a template parameter table, except that the template parameter is a type indicator or a constant value, the definition of the functional template looks the same as the definition of the template function.
During the execution of a program, type is replaced by a variety of built-in types and user-defined types. The size is replaced by a variety of constant values, which are determined by the actual min () (Remember, the two uses of a function are calling it and taking its address). the replacement process for types and values is called Template instantiation (template instantiation).
When a name is declared as a template parameter, it can be used until the template declaration or definition ends. The template type parameter is used as a type indicator and can appear in the remainder of the template definition, and is used in exactly the same way as a built-in or user-defined type, such as declaring variables and forcing type conversions. Modulus non-type parameters are used as a constant value and can appear in the remainder of the template definition, which can be used where constants are required, perhaps by specifying the size of an array in an array declaration or as an initial value for an enumerated constant.
SIZE specifies the magnitude of the array parameter and initializes a const int value
Template <class Type, int size>
Type min (const type (&r_array) [size])
{
const int loc_size = size;
Type Loc_array[loc_size];
// ...
exception handling for function templates
Template parameters in a function template can be instantiated as various types, but errors can occur when the template arguments for the instantiated template parameter are not exactly the same:
Template<typename t>
void min (t &x, T &y)
{return (x<y) x:y; }
void func (int i, Char j)
{
Min (i, i);
Min (J, J);
Min (i, j);
Min (j, i);
}
The last two calls in the example are wrong, and the reason for the error is that, at the time of invocation, the compiler implicitly generates a template function on the type of the first encountered argument and uses it to check all template functions for consistency, such as the statement
Min (i, j);
The first encountered argument I is an integral type, the compiler interprets the template parameter as an integral type, and subsequent template argument J cannot be interpreted as an integral type with an error, and there is no implicit type conversion capability at this time. There are two ways to resolve this exception:
⑴ uses mandatory type conversion, such as the statement min (i, j), rewritten to Min (I,int (j));
⑵ function templates with non-template functions
There are two kinds of methods:
① a function body that borrows a function template
At this point, only the prototype of the template function is declared, and its function body borrows the function body of the function template. Rewrite the above example as follows:
Template<typename t>
void min (t &x, T &y)
{return (x<y) x:y; }
int min (int,int);
void func (int i, Char j)
{
Min (i, i);
Min (J, J);
Min (i, j);
Min (j, i);
}
There is no error in executing this program, because overloaded functions support implicit type conversions between data.
② to redefine the function body
Just like a normal overloaded function, redefine a complete, non-template function, which can take arbitrary parameters. In C + +, when a function template is overloaded with a non-template function of the same name, the following calling principles should be followed: find a function that exactly matches the parameter, and call it if found. If the argument exactly matches more than one function, the call is an error. Look for a function template that, if found, instantiates it to generate a matching template function and call it. If none of the above two fails, then a function overload method is used to generate a parameter match through a type conversion, which is invoked if found. If all three of the above fails and no matching function has been found, the call is an error.
A few points to note: If an object, function, or type is declared in the global domain with the same name as the template parameter, the global name is hidden. In the following example, the type of TMP is not double but the template parameter type:
typedef double TYPE;
Template <class type>
Type min (Type A, type B)
{
The TMP type is a template parameter type, not a global typedef
Type tmp = a < b? A:B;
return TMP;
The object or type declared in the function template definition cannot have the same name as the template parameter.
Template <class type>
Type min (Type A, type B)
{
Error: Re-declare template parameter type
typedef double TYPE;
Type tmp = a < b? A:B;
return TMP;
The template type parameter name can be used to specify the return value of the function template.
OK:T1 represents the return type of min (), T2 and T3 represent parameter types
Template <class T1, class T2, class t3>
T1 min (T2, T3); Template parameter names can only be used once in the same template parameter table, but template argument names may be reused between multiple function template declarations or definitions.
Error: Invalid reuse of template parameter name type
Template <class Type, class type>
Type min (type, type);
OK: The name type is reused between different templates
Template <class type>
Type min (type, type);
Template <class type>
Type Max (type, type); If a function template has more than one template type parameter, each template type parameter must precede the keyword class or typename.
OK: Keyword TypeName and class can be mixed
Template <typename T, class u>
T minus (t*, U);
Error: Must be <typename T, class u> or <typename T, TypeName u>
Template <typename T, u>
T sum (t*, U); To parse a template definition, the compiler must be able to distinguish between a type and an expression that is not a type. For the compiler, it is not always possible to distinguish which expressions in the template definition are types. For example, if the compiler encounters an expression parm::name in the template definition, and parm the template type parameter represents a class. So name refers to a type member of Parm.
Template <class Parm, class u>
Parm minus (parm* array, U value)
{
Parm::name * p;//This is a pointer declaration or multiplication.
}
The compiler does not know if name is a type, because it cannot find the definition of the class represented by Parm until the template is instantiated. In order for the compiler to parse the template definition, the user must instruct the compiler which expressions are type expressions, and tell the compiler that an expression is a type expression that is preceded by a keyword typename. For example, if we want the expression Parm::name for a function template minus () to be a type name, the entire expression is a pointer declaration. We should revise as follows:
Template <class Parm, class u>
Parm minus (parm* array, U value)
{
TypeName Parm::name * p;//OK: pointer declaration
}
The keyword typename can also be used in the template parameter table to indicate that a template parameter is a type.
As with non-template functions, function Templates can also be declared as inline or extern. The indicator should be placed behind the template parameter table, not before the keyword template.
OK: The keyword follows the template parameter table
Template <typename type>
Inline type min (type, type);
Inline function:
(1) What is an inline function.
Inline functions are those defined in the class body, which is the function of the function body placed in the class body.
(2) Why the inline function should be introduced.
Of course, the main purpose of introducing inline functions is to solve the problem of the efficiency of function calls in a program. In addition, we talked about macros in the front, and there's an example of this:
#define ABS (x) (x) >0? (x):-(x))
When ++i appears, the macro distorts our meaning, in other words: the definition of a macro can easily produce two of meaning.
We can see that the macro has some unavoidable problems, how to solve it. We have tried to replace the front.
Here we use inline functions to solve these problems.
(3) Why inline can replace macros.
1, the inline definition of the class's inline function, the function code is put into the symbol table, in the use of direct replacement, (like a macro expansion), without the overhead of the call, the efficiency is very high.
2, obviously, the inline function of the class is also a real function, when the compiler calls an inline function, it first checks the type of its arguments to ensure that the call is correct. Then do a series of related checks, just like any real function. This eliminates its hidden dangers and limitations.
3, inline can be a member of a class function, of course, you can use the protection of the class members and private members.
(4) The difference between inline functions and macros.
The difference between an inline function and a macro is that the macro is replaced by the preprocessor, and the inline function is implemented through compiler control. and the inline function is the real function, only when need to use, inline function like macro expansion, so cancel the function of the parameter stack, reduce the overhead of the call. You can invoke inline functions just as you would call a function without worrying about problems that arise from dealing with macros. The inline function is compared with the macro definition with parameters, their code efficiency is the same, but the inner get-together function is better than the macro definition, because inline functions follow the type and scope rules, it is more similar to the general function, in some compilers, once the inline extension, it will be the same as the normal function calls, more convenient.
(5) When to use the inline function.
inline functions, which are most widely used in C + + classes, should be used to define access functions. The classes we define generally define the data members as private or protected, so that the outside world cannot read and write directly to the data of our class members. Read-write for private or protected members must be performed using member interface functions. If we write these readings
A member function is defined as an inline function, which will achieve better efficiency.
Class A
{
Private:
int ntest;
Public:
int Readtest () {return ntest;}
void settest (int I) {ntest=i}
}
(6) How do I use inline functions?
We can use inline to define inline functions.
inline int A (int x) {return 2*x}
However, any function defined in the Description section of the class will automatically be considered an inline function.
(7) How to prevent the function from being inline.
If you use VC + +, you can use the/ob command-line arguments. Of course, you can also use #pragma auto_inline in your program to achieve the same goal.
Advantages and disadvantages of inline functions:
we can call it as a normal function, but because the inline function expands like a macro when needed, the execution speed is faster than the normal function. Of course, inline functions also have some limitations. Is that the function of the execution code can not be too much, if the function of the inline function is too large, the general compiler will discard the inline method, and the normal way to call the function. (In other words, you use inline functions, just to make a request to the compiler, the compiler can reject your request) so that inline functions are as efficient as normal function execution.
Precautions:
1. Loop and switch statements are not allowed within the inline function.
2. The definition of an inline function must occur before the inline function is called for the first time.