Article One understanding template type inferenceBasic Situation
The first is to define function templates and function calls as follows, during compilation , the compiler infers the types of T and Paramtype, which are fundamentally different because paramtype often contains modifiers such as const, references, etc.
Template<typename t>void// function template form // function call
where the type of T is the type of expr, the following t is int
Templat<typename t>void F (const t& param); int 0 // T-int
But the inference of the type of T is not only related to expr, but also to Paramtype. There are three types of cases:
- Paramtype is a pointer or reference type, but not a universal reference (Universal Reference)
If expr is a reference type, the reference section is ignored
Then the pattern matches expr and paramtype to determine t
passing a const object to a function template is legal, and T adds the corresponding const as follows
template<typename t>void F (t& param); int x = 27 const int cx = X; const int & Rx = x;f (x); // T, int, param, int& f (CX); // f (RX); //
The above example shows an lvalue reference parameter, as well as an rvalue application, and of course only an rvalue argument can pass in an rvalue reference parameter, but has no effect on type inference
The case of the const t&
template<typename t>void F (const t& param); int x = 27 const int cx = X; const int & Rx = x;f (x); // T, int, param, int& f (CX); // T, int, param, const int& f (RX); // T-int, param, const int&
The situation of t*
Template<typename t>void f (t* param); int - ; Const int *px = &x;f (// t int, param-int*/ T const int, param Const int*
- Paramtype is a generic reference
If expr is an lvalue, T and Paramtype are inferred as lvalue references. This is very unusual, first of all, this is the unique context of the template type T is inferred as a reference, and then even if the Paramtype syntax is an rvalue reference, it infers that the type is also an lvalue reference
If expr is an rvalue, then the rule of case one applies
Template<typename t>voidF (t&¶m);intx = -;Const intCX =x;Const int& rx =x;f (x);//x-Lvalue, T-int&, param-int&F (CX);//x, Lvalue, T, const int&, param, const int&F (RX);//x, Lvalue, T, const int&, param, const int&F -);//rvalue, T, int, param, int&&
When a generic reference is used, the lvalue real participates in the type inference of the rvalue argument, but there is no difference between the non-generic reference
- Paramtype is neither a pointer nor a reference
If expr is a reference type, the reference section is ignored
After ignoring the reference section, if expr is const or volatile, it also ignores the
Template<typename t>void f (T param); int - ; Const int cx = x; Const int & rx =// t, int, param t/ t, int, param t/ t, int, param-t
Because it is a copy, the const of the argument no longer takes effect
The following is a special case analysis
Template<typename t>void f (T param); Const Char Const " Fun with pointers " / T, const char*, param, const char*
PTR is passed by value, then the const of PTR needs to be discarded, then the type of param is const char*
array Arguments
Although the array type and pointer type can sometimes be converted (in many contexts the array is degraded to a pointer to the first element, array-to-pointer decay rule), it is still worth discussing some detail issues.
Does not actually have an array-type parameter, it is converted to a pointer
General Array Scenarios
Template<typename t>void f (T param); Const Char " J. P. Briggs"// T, const char*, param, const char*
Referencing array Scenarios
Template<typename t>void f (t& param); Const Char " J. P. Briggs"// T-, const char[13], param, const char (&) [J]
The following function can get the length of the known quantity group directly in the compiler
Template<typename T, std::size_t n>constexpr std::size_t arraySize (t (&) [N]) noexcept { return N;}
function Arguments
The function type is also degraded to the function pointer type, with the same rules and array
void somefunc (intdouble); template<typename t>void F1 (T param); template<typename t>void F2 (t&// T-Void (*) (int, double), param, Void (*) (int, double)// T, param, Void (&) (int, double)
Summary
- Reference arguments are treated as non-referenced during template type inference, so their citations are ignored
- Lvalue arguments are treated differently when the formal parameters of a generic reference are inferred
- When inferring the type of a parameter, const, volatile arguments ignore its const, volatile
- During template type inference, the arguments of an array or function are degraded to pointers unless they are used to initialize the reference
[Effective modern C + +] Item 1. Understand template type deduction-Learn about templating types inference