The min algorithm is normally expressed like this:
template <typename T>
const T& min(const T& x, const T& y)
{
return y < x ? y : x;
}
However, this does not allow constructs of the form min(a, b) = 0
. You can achieve that with an additional overload:
template <typename T>
T& min(T& x, T& y)
{
return y < x ? y : x;
}
What I would like to do is unify these two overloads via perfect forwarding:
template <typename T>
T&& min(T&& x, T&& y)
{
return y < x ? std::forward<T>(y) : std::forward<T>(x);
}
However, g++ 4.5.0 spits out a warning for min(2, 4)
that I return a reference to a temporary. Did I do something wrong?
Okay, I get it. The problem is with the conditional operator. In my first solution, if I call min(2, 4)
the conditional operator sees an xvalue and thus moves from the forwarded x
to produce a temporary object. Of course it would be dangerous to return that by reference! If I forward the whole expression instead of x
and y
seperately, the compiler does not complain anymore:
template <typename T>
T&& min(T&& x, T&& y)
{
return std::forward<T>(y < x ? y : x);
}
Okay, I got rid of the references for arithmetic types :)
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type
min(T x, T y)
{
return y < x ? y : x;
}
template <typename T>
typename std::enable_if<!std::is_arithmetic<T>::value, T&&>::type
min(T&& x, T&& y)
{
return std::forward<T>(y < x ? y : x);
}