std::function_ref borrows a callable instead of owning it
For years the default way to take a callback in C++ was std::function, and for years it was the wrong default. The type std::function owns its callable. Passing a lambda to a std::function parameter copies it. If the closure is too big for the small-object buffer, that copy allocates. When all you do is call the thing and return, you paid for ownership you never used.
C++26 adds the type that most callback parameters actually wanted: std::function_ref (P0792). It is a non-owning reference to a callable. It stores a pointer to your callable and a pointer to how to invoke it, nothing more. There is no copy, no allocation, and no ownership. It does for callbacks what string_view does for strings.
The function transform_sum takes a single std::function_ref<int(int)>. The demo hands it two very different callables: a lambda that captures a local bias, and an ordinary function pointer. Both bind to the same parameter type and run, with nothing copied and nothing allocated:
capturing lambda -> 50
function pointer -> 30
When to reach for it
The distinction is about lifetime, and it is easy to state:
std::function_refwhen you will call the callable during the current call and not keep it. Predicates, visitors, comparators, “for each” callbacks, dependency-injected hooks invoked inline. This is the common case.std::functionwhen you must store the callable. It outlives the caller’s stack frame. Examples: an event handler kept in a member, a task pushed onto a queue, a continuation saved for later.
The trap is the same one string_view has. A function_ref object does not extend the lifetime of what it points at. Binding one to a temporary and storing it leaves a dangling reference. The type is built for parameters, and used as a parameter it is exactly right: pass any callable, pay for none of it.
C++23 already shipped std::move_only_function for the owning-but-not-copyable case. The new type completes the set by covering the borrowing case. Between the three, “just use std::function” is finally the wrong answer more often than the right one.
Sources: P0792R14 “function_ref: a type-erased callable reference” · cppreference: std::function_ref.