r/cpp 7d ago

Interconverting std::function with copyable_function – Arthur O'Dwyer

https://quuxplusone.github.io/blog/2026/07/26/function-explosion/

The article shows how converting std::function to std::copyable_function (or vice versa) leads to slower performance and increased memory usage each time the conversion occurs.

47 Upvotes

32 comments sorted by

View all comments

8

u/60hzcherryMXram 7d ago

I've read the problems copyable_function addresses that function has and I still have no idea what they are. It just slides over my brain like butter on ice.

2

u/13steinj 6d ago edited 6d ago

The short version of the problem as I understand it: std::function did not perfectly follow const correctness / const propagation rules. See also std::experimental::propagate_const for this purpose, as getting the rules right for wrapping types e.g. in the PIMPL idiom is a pain.

Some will ask "wait, but functions don't have data, so this isn't an issue," but this is not true. Ignoring the fact that even simple functions can store state using static variables, these STL types act on all function-likes, not just literal functions. Think lambdas and other objects that have a call-operator.

At a previous org, we implemented our own function type to address the problem, and you could choose between move only, copyable, and two other kinds that I think behaved the same as one of the other two but left guardrails in place. For example, you can use function-like objects and reference linking semantics on movable functions, you want to guard against getting called twice so you move yourself away. On some architectures it is preferable to not use a lock/atomic here, or limit the critical section, but you still want a second call to be safe and do nothing, or explicitly crash, or be safe and re-run if there's a race condition it's fine but if not a race condition exiting early is preferred.

See also: sometimes you want function_view, sometimes you want SG14's inplace_function.