Defined in Elimination of the algebraic structures unpacks products and dispatches over alternatives by ordinary C overload resolution and fuses per alternative lambdas into one overload set Dispatch is exhaustive an alternative without a viable arm makes the whole call not applicable apply apply_r overload Defined in Applicability traits fn apply fn overload template <typename Fn typename Args> constexpr auto apply Fn &&fn Args && args > apply_result_t<Fn Args > 1 The multidispatch entry point unpacks products dispatches over alternatives invokes fn A pack operand spreads into the call by elements a lone tuple like argument has std apply s meaning a copack operand dispatches on its active alternative itself unpacked one level when tuple like several pack copack operands first fold into one distributing alternatives over products The arm is selected by ordinary C overload resolution and the dispatch is exhaustive an alternative without a viable arm makes the whole call not applicable return Result of invoking fn on the selected call shape fn Fn && Callable fn overload fuses per alternative arms into one args Args && Any mix of scalars pack s and copack s in call order template <typename Ret typename Fn typename Args> constexpr auto apply_r Fn &&fn Args && args > Ret 1 fn apply with the result converted to Ret Branch results need only be acceptable as Ret which is how alternatives eliminating into different types converge name a type they all convert into every alternative converts implicitly into its parent copack so a copack_for of the branch results always serves return Result of the dispatch converted to Ret fn Fn && Callable fn overload fuses per alternative arms into one args Args && Any mix of scalars pack s and copack s in call order return Result of the dispatch converted to Ret fn Fn && Callable fn overload fuses per alternative arms into one args Args && Any mix of scalars pack s and copack s in call order Fuses callables into a single overload set The routing helper for multidispatch apply over a copack or choice selects the arm by ordinary overload resolution and a missing arm is a compile error An unconstrained auto arm serves every alternative which defeats that exhaustiveness check where one arm should serve several alternatives constrain it with a concept instead template <typename Fn typename Args> using apply_result_t typename apply_result<Fn Args > type 1 Alias for apply_result<Fn Args > type template <typename Fn typename Args> constexpr bool is_applicable_v is_applicable<Fn Args > value 1 Alias for is_applicable<Fn Args > value template <typename Ret typename Fn typename Args> constexpr bool is_applicable_r_v is_applicable_r<Ret Fn Args > value 1 Alias for is_applicable_r<Ret Fn Args > value template <typename Fn typename Args> constexpr bool is_nothrow_applicable_v is_nothrow_applicable<Fn Args > value 1 Alias for is_nothrow_applicable<Fn Args > value template <typename Ret typename Fn typename Args> constexpr bool is_nothrow_applicable_r_v is_nothrow_applicable_r<Ret Fn Args > value 1 Alias for is_nothrow_applicable_r<Ret Fn Args > value Checks if fn apply_r<Ret> of Fn over the arguments is viable As is_applicable except every branch result needs only to be acceptable as Ret rather than converge on one deduced type Checks if fn apply_r<Ret> of Fn over the arguments is viable and cannot throw