1

I need to pass a lambda with captures to a function, but I'm trying to avoid using std::function because of slow performance, and I'm making a performance critical application. I also would prefer to not use a template because the return type and parameters are specific, but I can use a template if it's the only way.

I already tried ChatGPTs answer and it didnt work:

void my_func(void (*callback)(int, int, int))
{
    callback(1, 2, 3);
}

int main()
{
    int x = 10;

    my_func([&](int a, int b, int c)
    {
        std::cout << "Example, a + b + c + x: " << a + b + c + x << std::endl;
    });

    return 0;
}

The error says:

no suitable conversion function from "lambda [](int a, int b, int c)->void" to "void (*)(int, int, int)" exists

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
ITDW
  • 148
  • 8
  • 3
    Template is the only way. You can restrict the signature via concepts if you're on C++20 or newer. – Wutz Apr 18 '23 at 20:27
  • 4
    This would work if `x` wasn't captured. As soon as you capture, the lambda has to carry around state information, and a function pointer's not smart enough to do that. – user4581301 Apr 18 '23 at 20:31
  • The template would likely perform much better than function pointers or std::function – user102008 Apr 19 '23 at 22:58

1 Answers1

7

You can pass a lambda as function pointer - but only if there's no captures involved.

This works:

void my_func(void (*callback)(int, int, int)) {
    callback(1, 2, 3);
}

int main() {
    my_func([](int a, int b, int c) {
        int x = 10;
        std::cout << "Example, a + b + c + x: " << a + b + c + x << std::endl;
    });

    return 0;
}

x in the above example can also be declared global.

int x;

int main()
{
    x = 10;

    my_func([](int a, int b, int c) {
        std::cout << "Example, a + b + c + x: " << a + b + c + x << std::endl;
    });

    return 0;
}

selbie
  • 100,020
  • 15
  • 103
  • 173