sum::apply/apply_r accept trailing arguments after the alternative's content — the member leg of fn::apply's engine protocol: the free function dispatches fn::apply(fn, sum, extras...) through the member, and the multi-operand fold recurses the same way. The rest of the family never got the same shape, for no design reason: apply_type/apply_type_r have no free-function counterpart, so nothing forced the arguments onto them, and choice is an atom to the engine (free apply never dispatches it), so its members stayed minimal. The internal machinery already anticipates the arguments — the type-indexed _invoke_type is variadic, and the tag prepender forwards whatever follows the tag.
Rectify additively, keeping sum::apply's shape (the engine protocol cannot narrow):
sum::apply_type and apply_type_r accept trailing arguments, appended after the alternative's unpacked content: arms become (tag, elements..., extras...).
- Parity across the family:
choice's apply/apply_r/apply_type/apply_type_r, and optional/expected's apply_type/apply_type_r, accept trailing arguments the same way (their untagged apply/apply_r already do). On optional, the empty arm receives (std::nullopt_t, extras...), mirroring the untagged empty arm's (extras...); expected<void, E>'s value arm likewise (std::in_place_t, extras...).
Intended for release-0.1: the family's shape should settle before the first tag.
sum::apply/apply_raccept trailing arguments after the alternative's content — the member leg offn::apply's engine protocol: the free function dispatchesfn::apply(fn, sum, extras...)through the member, and the multi-operand fold recurses the same way. The rest of the family never got the same shape, for no design reason:apply_type/apply_type_rhave no free-function counterpart, so nothing forced the arguments onto them, andchoiceis an atom to the engine (freeapplynever dispatches it), so its members stayed minimal. The internal machinery already anticipates the arguments — the type-indexed_invoke_typeis variadic, and the tag prepender forwards whatever follows the tag.Rectify additively, keeping
sum::apply's shape (the engine protocol cannot narrow):sum::apply_typeandapply_type_raccept trailing arguments, appended after the alternative's unpacked content: arms become(tag, elements..., extras...).choice'sapply/apply_r/apply_type/apply_type_r, andoptional/expected'sapply_type/apply_type_r, accept trailing arguments the same way (their untaggedapply/apply_ralready do). Onoptional, the empty arm receives(std::nullopt_t, extras...), mirroring the untagged empty arm's(extras...);expected<void, E>'s value arm likewise(std::in_place_t, extras...).Intended for release-0.1: the family's shape should settle before the first tag.