With the introduction of deducing this in C++23, variants in C++26 will have a member visit P2637R3, which is a great feature. I wonder, is it good to also add member apply to tuple-like objects? For example:
auto sum = std::tuple{0, 'a'}.apply(std::plus{});
auto dist = ranges::subrange{...}.apply([](auto i, auto s) { return s - i; });
Is this consistency superfluous, or does it have some value? One benefit I can think of is that this enables us to write the form of
tuple.apply(...).apply(...).apply(...).apply(...)
which may be an enhancement. What do you think?
IMHO it's a small usability improvement, but it has a problem with naming.
Normally we "apply" a function to a tuple: apply(f,t).
Here, you're applying a tuple to a function: t.apply(f).
This suggests that a different name (or a slightly different declension/conjugation/whatever) might be in order. I have no good suggestions, though. `t.apply(f)` is probably at least a local optimum.
(`visit` was easier to sell, because we all know that the original `std::visit(f,v)` took its arguments in the wrong order, so `v.visit(f)` was just correcting that "bug." I don't think there's nearly so much of a consensus that `std::apply(f,t)` should always have been `std::apply(t,f)`.)
The possibility of `t.apply(f1).apply(f2)` suggests that maybe the name should be drawn by analogy from `optional.and_then(f)` or `optional.transform(f)`. The notion in both cases is roughly "unwrap the contents and apply a function to them." But of course they're not directly comparable, and I also don't think either `tuple.and_then` or `tuple.transform` are good names for what this does.
I don't think it's worth LEWG's time to discuss.
–Arthur