The following definition of a min
function
template
constexpr auto
min(T&& t, U&& u) -> declty
The issue may be with the decltype()
rules.
This is hinted at; if the trailing return type is removed
template
constexpr auto
min(T&& t, U&& u)
{
return t < u ? t : u;
}
and the compiler is allowed to deduce it, the return type is int.
Use of decltype
decltype ( expression )
...
if the value category of expression is lvalue, then the decltype specifies T&
Taken from cppreference.
Since the expression involving t
and u
is an lvalue (they are lvalues - named r-value references), the return is the lvalue reference.
In this situation it leads to a potential situation where a literal could be modified. Careful use of forwarding needs to be applied when using "universal references" (or "forwarding references") and the associated reference collapsing rules.
As you have already noted, to correct the situation, the correct use of std::forward
needs to be applied and the return type will be the expected one.
For further details on std::forward and reference collapsing can be found here on SO.