Function template type inference at runtime
I am trying to figure out why the following compiles / runs despite the template type being resolved at runtime. This is because the calls if/else
only f
need to tell the compiler to create void f<double>(double)
and void f<std::string>(std::string)
?
test.hpp
#include <type_traits>
#include <string>
#include <iostream>
template <typename T>
void f(T x) {
if(std::is_same<T, std::string>::value)
std::cout << "String: " << x;
}
test.cpp
#include <iostream>
#include "test.hpp"
int main(int, char** argv) {
double x(std::stod(argv[1]));
if(x < 42) f(x);
else f(std::to_string(x));
return 0;
}
$ (clan)g++ -std=c++14 test.cpp
$ ./a.exe 41
$ ./a.exe 43
String: 43.000000
source to share
There are no runtime pattern deductions here. When you have
if(x < 42) f(x);
The compiler knows at compile time what x
is double, so it prints
void f<double>(double)
Then in
else f(std::to_string(x));
The compiler knows what the return type std::to_string
is std::string
, so it prints
void f<std::string>(std::string)
Use. Both functions exist at the same time, and only one call is called at runtime, depending on what input you provide to the program.
Let's see this example code provided by chris in his comment . Using
#include <type_traits>
template <typename T>
__attribute__((used)) int f(T x) {
if(std::is_same<T, int>::value)
return 1;
else
return 2;
}
int main(int argc, char** argv) {
if(argc > 1) return f(1);
else return f(1.0);
}
Compiling with -O3 -std=c++1z -Wall -Wextra -pedantic
creates an assembly
main: # @main
xor eax, eax
cmp edi, 2
setl al
inc eax
ret
int f<int>(int): # @int f<int>(int)
mov eax, 1
ret
int f<double>(double): # @int f<double>(double)
mov eax, 2
ret
As you can see, how the template functions exist in the assembly, but only if
in the master that decides which one to call at runtime.
source to share