Doubt about SFINAE

5

How the compiler resolves the case in which it can substitute more than one template and does not give ambiguity using the SFINAE principle.

#include <stdio.h>
#include <iostream>

template<typename T, typename U>
U cast(T x){
    return static_cast<U>(x);
    }

template<typename T, typename U>
T cast(U x){
    return static_cast<T>(x);

}

if we try this:

int main(int argc, char const *argv[])
{

    std::cout << cast<int,float>(10) << "\n";
    return 0;
}

is printed 10, however if we try:

 int main(int argc, char const *argv[])
{

    std::cout << cast<int,float>(10.34) << "\n";
    return 0;
}

gives the following compilation error:

  

more than one instance of overloaded function "cast" matches the argument > list: - function template "U cast (T x)" - function template "T>> cast (U x)" - argument types are: (double)

Does anyone know why this happens?

    
asked by Jki 09.10.2018 в 15:52
source

1 answer

3

The problem is that you are assuming that 10.34 is a float when, really, it is a double . This causes the compiler to find two candidate templates and, because both are equal to bad , it shows you the error and remains so calm.

The error is also reproduced when we replace the templates with functions to use :

float cast(int x){
  return static_cast<float>(x);
}

int cast(float x){
  return static_cast<int>(x);
}

int main(int , char const **)
{
  std::cout << cast(10.5) << '\n';

  return 0;
}

The error that is generated then is the following:

prog.cc:18:13: error: call to 'cast' is ambiguous
  int res = cast(10.5);
            ^~~~
prog.cc:5:7: note: candidate function
float cast(int x){
      ^
prog.cc:9:5: note: candidate function
int cast(float x){

Now, returning to the subject of the templates, it is enough to change the specialization to double so that the error disappears:

std::cout << cast<int,double>(10.34) << "\n";

Of course we also have, as a possible solution, to force the number to be float :

std::cout << cast<int,float>(10.34f) << "\n"
    
answered by 10.10.2018 в 18:22