On Tue, Nov 17, 2020 at 5:45 AM Pilar Latiesa via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
[...]

std::ranges::transform(std::views::zip(v, w, y), u.begin(), [](auto
&&Proxy) { auto [a, b, c] = Proxy; return a * b / std::sqrt(c); });

The question is: would it be theoretically possible to add overloads
to the algorithms such that they accept n-ary callables for iterators
with tuple-like iter_reference_t, where n is
tuple_size<iter_reference_t>?

std::ranges::transform(std::views::zip(v, w, y), u.begin(), [](auto a,
auto b, auto c) { return a * b / std::sqrt(c); });

There has definitely been at least an informal proposal for structured bindings in function parameters, like this:

    std::ranges::transform(std::views::zip(v, w, y), u.begin(), [](auto [a,b,c]) { return a * b / std::sqrt(c); });

This would be much easier to implement (as a core-language feature) than the library thing you're proposing.
(Has this ever been a real proposal paper? What happened with it?)

Are there cases in which adding such overloads would cause ambiguities?

Obviously yes (because it's C++)... but also, pretty obviously via a constructive proof. You just need to find a function that's callable with both 1 argument and 2 arguments. Such as any variadic lambda.

    // https://godbolt.org/z/3o89do
    auto arity = [](auto... ts) { return sizeof...(ts); };
    std::map<int, int> m = {{1,2}, {3,4}};
    std::ranges::transform(m, std::ostream_iterator<int>(std::cout), arity); // "11" today, "22" tomorrow?

And if you combined this with generic code it would get even weirder. "What do you mean, 'it automatically explodes the element type T if-and-only-if T is destructurable'? How do I iterate over the elements then?"

–Arthur

(Serendipitously, I was just talking about the badness of APIs that try to guess the user's meaning in the "vertical" direction; this one is trying to guess the user's meaning in the "horizontal" direction. For its "vertical" analogue, see recursive_count_if.)