Lambda expressions are implemented by creating a class with an overloaded function call operator and referencing variables as members. This suggests that the size of lambda expressions varies depending on the number of referenced variables. However, std::function must have a fixed size. Understanding the implementation of std::function is crucial.
Type Erasure for Variable Size Functors
std::function employs a technique called type-erasure to handle functors of variable sizes. Consider a simplified example of std::function that wraps a function pointer to int(double):
struct callable_base { virtual int operator()(double d) = 0; virtual ~callable_base() {} }; template <typename F> struct callable : callable_base { F functor; callable(F functor) : functor(functor) {} virtual int operator()(double d) { return functor(d); } }; class function_int_double { std::unique_ptr<callable_base> c; public: template <typename F> function(F f) { c.reset(new callable<F>(f)); } int operator()(double d) { return c(d); } };
In this example, std::function stores a unique_ptr to the polymorphic callable_base type. For different functors, new types derived from callable_base are created and instantiated dynamically. The std::function object maintains a consistent size while accommodating functors of various sizes in the heap.
Dynamic Dispatch & Optimization
To improve performance, real-world implementations of std::function optimize dynamic dispatch and leverage small object optimizations. However, the underlying concept remains the same.
Behavior of std::function Copies
Copies of std::function are accompanied by copies of the callable object they encapsulate. This is confirmed by the following test:
int main() { int value = 5; typedef std::function<void()> fun; fun f1 = [=]() mutable { std::cout << value++ << '\n' }; fun f2 = f1; f1(); fun f3 = f1; f2(); f3(); }
The output демонстрирует (5, 5, 6), indicating that copies of the function object are made, rather than sharing the state.
This understanding of std::function's implementation ensures its efficient use with functors of varying sizes.
The above is the detailed content of How Does `std::function` Handle Functors of Variable Sizes?. For more information, please follow other related articles on the PHP Chinese website!