Home > Net >  Get function pointer from std::function that holds lambda
Get function pointer from std::function that holds lambda

Time:10-20

I want to get the raw function pointer from an std::function that has been assigned a lambda expression.

When std::function is assigned a regular function, this works as expected:

#include <functional>
#include <iostream>

bool my_function(int x) {}
using my_type = bool(*)(int);
int main() {
    std::function f = my_function;
    auto pointer = f.target<my_type>();

    // Prints 1
    std::cout << (pointer != nullptr) << std::endl;
    return 0;
}

However, when I change this example to use a lambda, it does not work:

#include <functional>
#include <iostream>

using my_type = bool(*)(int);
int main() {
    std::function f = [](int) -> bool {};
    auto pointer = f.target<my_type>();

    // Prints 0
    std::cout << (pointer != nullptr) << std::endl;
    return 0;
}

Why does the second example print 0 and how could it be fixed to print 1?

CodePudding user response:

Your trouble is the type of the lambda is NOT my_type. It's an unspecified type.

Try this:

#include <functional>
#include <iostream>

int main() {
    auto lambda = [](int x) -> bool { return x != 0; };
    std::function f = lambda;
    auto pointer = f.target<decltype(lambda)>();

    // Prints 1
    std::cout << (pointer != nullptr) << std::endl;
    return 0;
}

CodePudding user response:

Based on the OP's comment that what he wants is something he can pass as a callback parameter to a C function, here is some quick proof-of-concept code that shows how to do that with a capturing lambda. Please excuse the C-style casts but it's late and I'm tired. reinterpret_cast should work just fine.

#include <iostream>
#include <functional>

void example_c_function (void (* callback) (void *context), void *context)
{
    callback (context);
}

int main ()
{
    int i = 42;
    std::function <void (void)> f = [=] { std::cout << i; };

    void (* callback) (void *) =  [] (void *context)
    {
        auto call_me = (std::function <void (void)> *) context;
        (*call_me) ();
    };

    example_c_function (callback, (void *) &f);
}

Output: 42 (yay!)

Live Demo

Does that help, OP?

  • Related