I saw the example code for template function max.
template <typename T1,
typename T2,
typename RT = std::decay_t<decltype(true ? std::declval<T1>()
: std::declval<T2>())>>
RT max (T1 a, T2 b) {
return b < a ? a : b;
}
I know what is decltype and declval. But I couldn't understand why it uses ternary operator with always true to deduce return type.
If I use max(1, 2.5) it returns double type of 2.5, which means RT is deduced to second parameter T2 or double. How is it possible even though decltype returns only type of T1?
(I know I can use auto for return type to simplify code. But my purpose is to understand the usage of weird code.)
std::decay_t<decltype(true ? std::declval<T1>() : std::declval<T2>())>is a way of obtaining the "common type" ofT1andT2. Presumably, ifT1 = intandT2 = double, this is intended to bedoublebecauseintwould be converted todoublein an expression such asint{...} + double{...}.See What is the result type of '?:' (ternary/conditional operator)?
Note that
std::declvalreturns an rvalue reference, andstd::decay_tremoves that reference qualification so thatRTis not a reference, but an object type.More commonly, people use
std:common_type_twhich uses the conditional operator as one of the ways of obtaining a common type.Or alternatively: