September 25, 2022

COSFONE

Networking, PBX, IT, DIY Solution

C++ function templates: Limitations Instantiation and Reification

5 min read

C++ function templates: Limitations Instantiation and Reification



 

C++ function templates: Limitations Instantiation and Reification.

 

template<typename T>
void Swap(T &a ,T &b){
    T temp;
    temp = a;
    a = b;
    b = temp;
}

When using a template function, the compiler generates the corresponding function definition based on the actual type.

 

overloaded template

Not all types use the same algorithm, and template function definitions can be overloaded like regular functions.

template<typename T>
void Swap(T &a ,T &b); //#1

template<typename T>
void Swap(T *a ,T *b,int n);//#2 the last parameter is a specific type

int main(){
    int i =10,j=20;
    Swap(i,j);//use #1
    
    const int Lim = 8;
    int d1[Lim]={0,1,2,3,4,5,6,7};
    int d2[Lim]={7,6,5,4,3,2,1,0};
    Swap(d1,d2,Lim);//use #2
}
template<typename T>
void Swap(T &a ,T &b){
    T temp;
    temp = a;
    a = b;
    b = temp;
}

template<typename T>
void Swap(T *a ,T *b,int n){
    T temp;
    for(int i=0;i<n;i++)
    {
        temp =a[i];
        a[i]=b[i];
        b[i]=temp;
    }
}

 

 

Template limitations

In some cases, the corresponding operation of type T is only applicable to arrays. If T is a structure, the template function does not hold.

Likewise, if(a>b)if T is a structure, > does not hold

solution:

  1. overloaded operator symbols
  2. Provides a reified template definition for a specific type

 

 

Show incarnation

When the compiler finds a reified definition that matches a function call, it will use that definition and no longer look for templates.

  • For a given function name, there can be non-template functions, template functions, and explicit reified template functions and their overloaded versions.
  • Shows that reified prototypes and definitions template<>begin with and indicate the type by name
  • The calling order is: non-template function > reified template function > template function
void Swap(job& ,job&);

template <typename T>
void Swap(T&,T&);

template<> void Swap<job>(job& ,job&);//show incarnation
//<job> in Swap<job> is optional, because the parameter type of the function indicates that this is a reification of job, so it can also be written like this: template<> void Swap(job& ,job&);

 

 

 

Instantiation and reification

Note: A function template does not generate a function definition, it just generates a scheme for generating a function definition. When the compiler uses a template to generate a function definition for a specific type, it gets a template instance.

template<typename T>
void Swap(T &a ,T &b);

int a =10,b=20;
Swap(a,b);//Because a parameter of type int is provided, a template instance of type int is automatically generated. This is == implicit instantiation == 
//You can also directly instruct the compiler to create a specific instance//Display instantiation template void Swap<int>(int &,int &);
//Use Swap() template to generate int function definition of type
//show incarnation template<> void Swap<int>(int& ,int&); template<> void Swap(int& ,int&); //The difference is: Concretization does not use the Swap() template function to generate a function definition, but uses a function definition specifically defined for the int type.
//Simple understanding, concretization is a declaration of a function, and instantiation is a Use of template functions
template<typename T>
T Add(T a,T b){
    return a+b;
}

int m=6;
double x=10.5;
Add<double>(x,m); //Does not match with Add(x,m), because one is int and the other is double 
//Instantiation by Add<double>, m can be forced to be converted to double
//But the same can not be successful for Swap, because Swap uses is a reference type Swap<double>(m,x);//double& cannot point to int
//Example case
template <typename T>
void Swap(T &,T &);

template<> void Swap<job>(job&,job&);//具体化
int mian(){
    template void Swap<char>(char& ,char&);
    
    short a,b;
    Swap(a,b);//Implicit instantiation
    
    job n,m;
    Swap(n,m);//show incarnation
    
    char g,h;
    Swap(g,h);//show instantiation
}

 

 

 

Determination of template function type

template<class T1,class T2>
void fun(T1 x,T2 y){
    ?type? s=x+y; //Because it is a template function, the type of ?type? is uncertain at this time
}

C++11 adds decltypekeywords

template<class T1,class T2>
void fun(T1 x,T2 y){
    decltype(x+y) s=x+y; //The type of s is the same as the type of x+y
}

Steps to use decltype(expression) var:

  1. If expression is not enclosed in parentheses, then var has the same type as expression, including qualifiers such as const
double x =5.5;
double& z =x;
const double* pd;
decltype(x) w; //w is double type
decltype(z) u; //u is double& type
decltype(pd) v; //v is const double* type
  1. If expression is a function call, then var has the same type as the return value. does not actually call the function, the compiler determines the return type by looking at the prototype
  2. If expression is an lvalue, then var is a reference to its type. Common situations are as follows:
double x = 4.5;
decltype((x)) r = x;//r is double& type
decltype(x) r = x;//r is double type

// Parentheses do not change the value and lvalue of expression
//It can be understood that adding parentheses is only a way of decltype statement reference
  1. If none of the first 3 are satisfied, then var has the same type as expression
int j=3;
int &k=j;
int &n=j;

decltype(j+6) x; //x is int
decltype(k+n) y;//y is an int, although k and n are references, but k+n is not a reference is the sum of 2 ints

If declared multiple times, it is possible to combine typedefanddecltype

typedef decltype(x+y) xytype;
xytype z = x+y;
xytype arr[10];

However, some function templates that need to define the return value type still cannot be solved, such as:

template<class T1,class T2>
?type? fun(T1 x,T2 y) //The type cannot be determined at this time
{
    return x+y;
}

C++ adds a new syntax auto h(int x,float y) -> double, which is called a post-return type, and auto is a placeholder

template<class T1,class T2>
auto fun(T1 x,T2 y)->decltype(x+y) //The post type uses decltype{
    return x+y;
}
 
 
 
 
 


Copyright © All rights reserved. | Newsphere by AF themes.