Explanation of std::function

前端 未结 6 1608
故里飘歌
故里飘歌 2020-12-31 09:58

What is the purpose of std::function? As far as I understand, std::function turns a function, functor, or lambda into a function object.

I

6条回答
  •  [愿得一人]
    2020-12-31 11:00

    What is the purpose of std::function? As far as I understand, std::function turns a function, functor, or lambda into a function object.

    std::function is an example of a broader concept called Type Erasure. The description you have isn't quite accurate. What std::function does, to pick a specific specialization, is represent any callable that can be invoked with no arguments. It could be a function pointer or a function object that has a concrete type, or a closure built from a lambda. It doesn't matter what the source type is, as long as it fits the contract - it just works. Instead of using the concrete source type, we "erase" it - and we just deal with std::function.

    Now, why would we ever use type erasure? After all, don't we have templates so that we can use the concrete types directly? And wouldn't that be more efficient and isn't C++ all about efficiency?!

    Sometimes, you cannot use the concrete types. An example that might be more familiar is regular object-oriented polymorphism. Why would we ever store a Base* when we could instead store a Derived*? Well, maybe we can't store a Derived*. Maybe we have lots of different Derived*s that different users use. Maybe we're writing a library that doesn't even know about Derived. This is also type erasure, just a different technique for it than the one std::function uses.

    A non-exhaust list of use-cases:

    • Need to store a potentially heterogenous list of objects, when we only care about them satisfying a concrete interface. For std::function, maybe I just have a std::vector> callbacks - which might all have different concrete types, but I don't care, I just need to call them.
    • Need to use across an API boundary (e.g. I can have a virtual function taking a std::function, but I can't have a virtual function template).
    • Returning from a factory function - we just need some object that satisfies some concept, we don't need a concrete thing (again, quite common in OO polymorphism, which is also type erasure).
    • Could potentially actually use templates everywhere, but the performance gain isn't worth the compilation hit.

提交回复
热议问题