https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120945
Bug ID: 120945 Summary: Missed optimization opportunity with std::bind_front Product: gcc Version: 15.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: Mark_B53 at yahoo dot com Target Milestone: --- In the following code compiled using -O2, test2() is fully optimized to "mov eax, 10" followed by "ret", whereas test1() invokes Foo::test in a loop. The difference between the functions is the use of an explicit lambda (test2) vs. a call wrapper generated by std::bind_front (test1). #include <ranges> #include <functional> #include <algorithm> struct Foo { bool test(int idx) const { return data[idx] == 0; } int data[10]; int count1() const { auto fn = std::bind_front(&Foo::test, this); return std::ranges::count_if(std::views::iota(0, 10), fn); } int count2() const { auto fn = [this](int idx) { return test(idx); }; return std::ranges::count_if(std::views::iota(0, 10), fn); } }; __attribute__((noinline)) int test1() { Foo foo{}; return foo.count1(); } __attribute__((noinline)) int test2() { Foo foo{}; return foo.count2(); } --- clang 19.1 is able to optimize both implementations. Although this fact is likely not relevant, I'm including it here since I am not a language lawyer on perfect forwarding call wrappers.