today in Theory of Programming Language class we have seen this behaviour in Java:
public class Es {
...
<Y> Y choose(Y y1, Y y2){
Y returnVal;
if("some test"){ returnVal = y1;} else{ returnVal = y2;}
return returnVal;
}
}
In Main:
Es c = new Es();
Integer i = 3;
Float f = (float) 4.5;
Number n = c.choose(i, f);
Where the "incredible" is that the method must choose between Integer and Float for the parametric type Y and opts for the nearest super-type, which is Number.
I would like to reproduce this in C++ but I am stuck...
Templates do not try adjusting types when they don't match. That's why a simple implementation like the following:
template <class Y>
Y choose(Y y1, Y y2) {
// ...
}
Fails with the following error:
main.cpp:8:5: fatal error: no matching function for call to 'choose'
choose(1, 2.5f);
^~~~~~
main.cpp:3:3: note: candidate template ignored:
deduced conflicting types for parameter 'Y' ('int' vs. 'float')
What you want to do is let the function template take in both types, then resolve the common type:
template <class Y1, class Y2>
auto choose(Y1 y1, Y2 y2) {
using Y = std::common_type_t<Y1, Y2>;
Y returnVal;
if("some test") {
returnVal = y1;
} else {
returnVal = y2;
}
return returnVal;
}
A good idea is to make the function SFINAE-friendly, by also lifting the type deduction into its signature:
template <class Y1, class Y2>
std::common_type_t<Y1, Y2> choose(Y1 y1, Y2 y2) {
// Same as before
}