From 64936afc45197d9c8e2702bf5d85cec53d1caf2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=9Fur=20G=C3=BCney?= Date: Sat, 11 Mar 2023 19:45:16 -0500 Subject: [PATCH] transform_reduce to fix count implementation Hi! while watching your talk on YouTube ran this logic on a small example and it didn't give me the correct result. https://en.cppreference.com/w/cpp/algorithm/reduce says the binary operation has to be associative and commutative. I think `a + (b == val)` is not. Because the way reduce goes over a vector `{a, b, c, d}` with `init` is: `R(R(R(a, b), R(c, d)), init)`, NOT `R(R(R(R(init, a), b), c), d)`. :-O I realized this when I saw the diagram for reduce in https://blog.tartanllama.xyz/accumulate-vs-reduce/. I watched further into your talk and learned about `transform_reduce`. ^_^ Using that we can make the binary op of `reduce` part of `transform_reduce` commutative and associative. Also I'm not an export. The way reduce goes over a vector could be compiler, platform dependent. Here is a Compiler Explorer comparison of `reduce` and `transform_reduce` versions: https://godbolt.org/z/r66M4cYsb Have a nice day! --- Talks/2019-05-CppNow/AlgorithmIntuition/Slide-078.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Talks/2019-05-CppNow/AlgorithmIntuition/Slide-078.cpp b/Talks/2019-05-CppNow/AlgorithmIntuition/Slide-078.cpp index 28a98b6..d1664a1 100644 --- a/Talks/2019-05-CppNow/AlgorithmIntuition/Slide-078.cpp +++ b/Talks/2019-05-CppNow/AlgorithmIntuition/Slide-078.cpp @@ -1,7 +1,9 @@ namespace my {    template    auto count(I f, I l, T const& val) -> int { -      return std::reduce(f, l, 0, -         [val](auto a, auto b) { return a + (b == val); }); +      return std::transform_reduce(f, l, 0, +         [](auto a, auto b) { return a + b; }, + [val](auto x) { return static_cast(x == val); } + );    } }