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

      

+3


source to share


2 answers


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.

+8


source


  • The compiler reads main

    , sees two calls f

    , once with a string argument and once with an int

  • Creates two f

    s. Calls to both functions are built into the main one.

  • Your if statement makes one call or another. So there is no template resolution at runtime. It doesn't exist.



+1


source







All Articles