When the compiler sees the call made to a function which happens to be created from a function template, it instantiates the function from the template. This is called function template instantiation. The function that gets instantiated is called specialization or just function instance.
The syntax for the call to be made to the templated function looks like below.
function<type>(arg...);
For example, min<int>(1, 2).
When the call min<int>(1, 2) is made, compiler generates the function using actual type int.
template <typename T>
T min(T a, T b)
{
return a < b ? a : b;
}
min<int>(1, 2);Compiler should create a concrete function like below.
template <>
int min<int>(int a, int b)
{
return a < b ? a : b;
}How to see if compiler does it?
- Compile the source file using -S flag.
- It should generate assembly code.
- Look for variables start with
__Z3(__Z3minin this case)- Copy that variable and pass it to command
c++filt.- It should give the readable function name. For example,
❯ c++filt __Z3minIiET_S0_S0_ int min<int>(int, int)
The final example that compiler actually compiles is,
#include <iostream>
template <typename T>
T min(T a, T b);
template <>
int min<int>(int a, int b)
{
return a < b ? a : b;
}
int main(int argc, char const *argv[])
{
std::cout << min<int>(2, 1.0);
return 0;
}We do not need definition for the template.
Template Type Deductions from Arguments
Compiler can deduce which type to use for template function from the arguments type when the call is made. For example, min(1, 2) would create function min<int>(int, int). So, we can use normal function call syntax instead of min<int>(1, 2).
Info
If there exist both template and non-template function, normal function call syntax would vouch for non-template function.
For example,
#include <iostream>
template <typename T>
T min(T a, T b)
{
return a < b ? a : b;
}
int main(int argc, char const *argv[])
{
std::cout << min<int>(2, 1);
std::cout << min(2, 1);
return 0;
}Both calling syntax would call min<int> function.