How std::function works

后端 未结 1 1016
南旧
南旧 2020-11-28 02:11

You know, we can wrap or store a lambda function to a std::function:

#include 
#include 
int main()
{
    std:         


        
相关标签:
1条回答
  • 2020-11-28 02:34

    It uses some type erasure technique.

    One possibility is to use mix subtype polymorphism with templates. Here's a simplified version, just to give a feel for the overall structure:

    template <typename T>
    struct function;
    
    template <typename Result, typename... Args>
    struct function<Result(Args...)> {
    private:
        // this is the bit that will erase the actual type
        struct concept {
            virtual Result operator()(Args...) const = 0;
        };
    
        // this template provides us derived classes from `concept`
        // that can store and invoke op() for any type
        template <typename T>
        struct model : concept {
            template <typename U>
            model(U&& u) : t(std::forward<U>(u)) {}
    
            Result operator()(Args... a) const override {
                t(std::forward<Args>(a)...);
            }
    
            T t;
        };
    
        // this is the actual storage
        // note how the `model<?>` type is not used here    
        std::unique_ptr<concept> fn;
    
    public:
        // construct a `model<T>`, but store it as a pointer to `concept`
        // this is where the erasure "happens"
        template <typename T,
            typename=typename std::enable_if<
                std::is_convertible<
                    decltype( t(std::declval<Args>()...) ),
                    Result
                >::value
            >::type>
        function(T&& t)
        : fn(new model<typename std::decay<T>::type>(std::forward<T>(t))) {}
    
        // do the virtual call    
        Result operator()(Args... args) const {
            return (*fn)(std::forward<Args>(args)...);
        }
    };
    

    (Note that I overlooked several things for the sake of simplicity: it cannot be copied, and maybe other problems; don't use this code in real code)

    0 讨论(0)
提交回复
热议问题