I am trying to understand better when decay or not a type
#include <type_traits>
template <typename T1, typename T2> auto max_test(T1 a, T2 b) -> typename std::decay<decltype(a > b ? a: b)>::type {
return a < b ? a : b;
}
template <typename T1, typename T2> auto max_test_r(T1 a, T2 b) -> decltype(a > b ? a: b) {
return a < b ? a : b;
}
Which is the most correct version and why? Should i avoid using decays or when should i use them?
The second if flawed, thanks to Adam for the answer. The problem is that you are decltyping an lvalue.
If a and b are the same literal type, your decay-less one returns a dangling reference.
Your decay one does not.
There are going to be a myriad of other less important differences, but that bug is pretty big.
Decay does specific things. When you should use it is when either you want those things to happen, or when you have a type you need to store a copy of as a value.
Which is the most correct version and why?
The correct one is the second one, without the std::decay as you want to return the same type of either a or b. That means either T1 or T2.
Should I avoid using
std::decays or when should I use them?
This has been better explained in this post: What is std::decay and when it should be used?
That being said, in C++17 you only need something without the trailing return.
template <typename T1, typename T2>
auto max_test_r(T1 a, T2 b)
{
return a > b ? a : b;
}
You use std::decay if you want the actual type without the const- volatile qualifiers.
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