//using template<int I> structint_ { staticconstexprint value = I; };
template<typename T, typename U> using add = int_<(T::value + U::value)>;
using result = typename loop<1>::template f<add, int_<1>, int_<3>, int_<4>, int_<5>, int_<6>>;
Не создаётся новый тип на каждый шаг алгоритма, переиспользуется уже существующий — разница на 2 порядка. Алгоритм loop<(sizeof...(Ts) > 0)> и тип f<add, int_<1>, int_<3>, int_<4>, int_<5>, int_<6>>; разделены.
//С - continuation template<typename C> structjoin { template<typename...Ts> using f = join_impl<C, Ts...>; };
template<typename F, typename C> structtransform { template<typename...Ts> using f = ucall<C, typename F::template f<Ts>...>; };
//using using result = ucall< flatten< filter<predicate, sort<less, remove_adjacent< is_same, fold_left<predicate>>>>>, Ts...>;
Элементы не собираются/разбираются в списки, а передаются по одному через композицию функций-продолжений (tacit programming/point free style, pipe) - сильно быстрее + чуть менее вырвиглазный синтакс.