Passing capturing lambda as function pointer

前端 未结 9 2226
-上瘾入骨i
-上瘾入骨i 2020-11-21 06:58

Is it possible to pass a lambda function as a function pointer? If so, I must be doing something incorrectly because I am getting a compile error.

Consider the follo

9条回答
  •  情话喂你
    2020-11-21 07:30

    Capturing lambdas cannot be converted to function pointers, as this answer pointed out.

    However, it is often quite a pain to supply a function pointer to an API that only accepts one. The most often cited method to do so is to provide a function and call a static object with it.

    static Callable callable;
    static bool wrapper()
    {
        return callable();
    }
    

    This is tedious. We take this idea further and automate the process of creating wrapper and make life much easier.

    #include
    #include
    
    template
    union storage
    {
        storage() {}
        std::decay_t callable;
    };
    
    template
    auto fnptr_(Callable&& c, Ret (*)(Args...))
    {
        static bool used = false;
        static storage s;
        using type = decltype(s.callable);
    
        if(used)
            s.callable.~type();
        new (&s.callable) type(std::forward(c));
        used = true;
    
        return [](Args... args) -> Ret {
            return Ret(s.callable(std::forward(args)...));
        };
    }
    
    template
    Fn* fnptr(Callable&& c)
    {
        return fnptr_(std::forward(c), (Fn*)nullptr);
    }
    

    And use it as

    void foo(void (*fn)())
    {
        fn();   
    }
    
    int main()
    {
        int i = 42;
        auto fn = fnptr([i]{std::cout << i;});
        foo(fn);  // compiles!
    }
    

    Live

    This is essentially declaring an anonymous function at each occurrence of fnptr.

    Note that invocations of fnptr overwrite the previously written callable given callables of the same type. We remedy this, to a certain degree, with the int parameter N.

    std::function func1, func2;
    auto fn1 = fnptr(func1);
    auto fn2 = fnptr(func2);  // different function
    

提交回复
热议问题