I don't think std::function does any dynamic allocation when you initialize it with simple functions. When you initialize it with function objects or lambda expression, most, if not all implementations use the small object optimization to avoid dynamic allocation when possible.