The sum arm of invocable_transform_error asks
{ FWD(v).error().transform(FWD(fn)) } -> convertible_to_expected<...>;
and for a void-returning callback the question does not answer — it explodes while forming sum::transform's return type: the collapsing machinery computes the flattened, normalized sum of the per-alternative invoke results, and a void result has no place in that computation, which fails outside any immediate context.
#include <fn/transform_error.hpp>
#include <fn/sum.hpp>
struct A final {};
struct B final {};
constexpr auto fnVoid = [](auto &&...) -> void {};
static_assert(not fn::invocable_transform_error<decltype(fnVoid), fn::expected<int, fn::sum_for<A, B>>>);
hard-errors on g++ and clang. The defect is in the machinery, not the concept — the same formation is reachable directly:
template <typename S, typename Fn>
concept can_transform = requires(S s, Fn fn) { static_cast<S &&>(s).transform(fn); };
static_assert(not can_transform<fn::sum_for<A, B> &, decltype(fnVoid)>);
is a hard error too. So a void guard on the concept would cover only the verb path; sum::transform (and whatever else forms this return type) needs to reject a void-producing callback in the immediate context. Distinct mechanism from #290/#293 (a result-type computation, not a conversion-target mandate) — needs its own investigation.
Reproduced at 58d131c with gcc 16.1.1 and clang 22.1.6 (x86-64 Linux).
The sum arm of
invocable_transform_errorasks{ FWD(v).error().transform(FWD(fn)) } -> convertible_to_expected<...>;and for a void-returning callback the question does not answer — it explodes while forming
sum::transform's return type: the collapsing machinery computes the flattened, normalized sum of the per-alternative invoke results, and a void result has no place in that computation, which fails outside any immediate context.hard-errors on g++ and clang. The defect is in the machinery, not the concept — the same formation is reachable directly:
is a hard error too. So a void guard on the concept would cover only the verb path;
sum::transform(and whatever else forms this return type) needs to reject a void-producing callback in the immediate context. Distinct mechanism from #290/#293 (a result-type computation, not a conversion-target mandate) — needs its own investigation.Reproduced at 58d131c with gcc 16.1.1 and clang 22.1.6 (x86-64 Linux).