I have a question about C++ templates. The following codes segfaults.
template <typename T1, typename T2>
inline T1 const& max(T1 const &a, T2 const &b) {
return a < b ? b : a;
}
int main() {
std::cout << max(4.9, 4) << std::endl;
}
However, remove the & and it does the right thing.
template<typename T1, typename T2>
inline T1 const max(T1 const &a, T2 const &b) {
return a < b ? b : a;
}
int main() {
std::cout << max(4.9, 4) << std::endl;
}
Furthermore, just use T instead of T1 and T2 and it works just fine.
template<typename T>
inline T const& max(T const &a, T const &b) {
return a < b ? b : a;
}
int main() {
std::cout << max(4, 5) << std::endl;
}
What am I doing wrong here ?
You should always compile with warnings turned on, see https://wandbox.org/permlink/KkhFOJw6QNJ7rv7J. If you had the warning flags on, the compiler would have helped you out and told you what you are doing wrong.
What is happening here is a promotion (see Return type of '?:' (ternary conditional operator)), you are executing a ternary expression on an int
and a double
. Doing that results in a temporary promoted double
. And returning a reference to a temporary and referencing that after the function where its lifetime is bound returns is undefined behavior.
In the two first, you are returning a reference to a temporary.
Why? Well, your function is returning the type T1
, but you will have to convert one of the types you send. The conversion creates a temporary of the right type. Then you're returning it.
Since the temporary dies, the returned reference is bound to a dead object.
You already found a fix. You either not returning a reference, or you either take parameters of the same type.
If you look at the standard implementation, it chose the second solution: taking parameters of the same type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With