I think you're conflating two new language features that ought to be
considered in isolation:
1. Automatic polymorphization of parameter types.
2. Automatic deduction of return types for non-lambda functions.
Thinking about how to add feature 1 in isolation, in a way that works
for all functions, function templates, and lambda functions, without the
above-mentioned ambiguity between parameters without names and those
without types, the solution that first occurs to me is the one suggested
by Robert Frunzke in a comment on your C++Next article: use "auto" in
place of the type name rather than omitting it.
So we would write
auto min(auto x, auto y)->decltype(x < y ? x : y)
{ return x < y ? x : y; }
which is equivalent to
template <class T, class U>
auto min(T x, U y)->decltype(x < y ? x : y)
{ return x < y ? x : y; }
And then, independently of that, we also allow the "->decltype..." to be
omitted by following the same rules as for lambdas.
Indeed, one might even want to omit both the type and the name of the
parameter, e.g.
void ignore(auto&&...) {}
This also expands more easily to more general pattern-matching, such as:
void f(std::vector<auto> const&);
which can fill in the type in the same way that function templates do.
Though of course it's less clear what to do with:
void f(std::pair<auto, auto> const&);
(my instinct is that the two autos should spawn independent template
parameters, but one might argue that they should be the same type)
But this is now getting rather off-topic...
John Bytheway