C++ Weekly - Ep 97 - Lambda To Function Pointer Conversion

preview_player
Показать описание
☟☟ Awesome T-Shirts! Sponsors! Books! ☟☟

T-SHIRTS AVAILABLE!

WANT MORE JASON?

SUPPORT THE CHANNEL

GET INVOLVED

JASON'S BOOKS

► C++23 Best Practices

► C++ Best Practices

JASON'S PUZZLE BOOKS

► Object Lifetime Puzzlers Book 1

► Object Lifetime Puzzlers Book 2

► Object Lifetime Puzzlers Book 3

► Copy and Reference Puzzlers Book 1

► Copy and Reference Puzzlers Book 2

► Copy and Reference Puzzlers Book 3

► OpCode Puzzlers Book 1


RECOMMENDED BOOKS

AWESOME PROJECTS

O'Reilly VIDEOS

Source:
Рекомендации по теме
Комментарии
Автор

You forgot to mention the unary plus operator of a captureless lambda, which explicitly casts it to a function pointer:

auto lambda = [](int a, int b) { return a + b; };

auto funptr = +[](int a, int b) { return a + b; };
// same as
//auto funptr = (int(*)(int, int))[](int a, int b) { return a + b; };

//static_assert(std::is_same_v<decltype(lambda), int(*)(int, int)>, "This fails");
static_assert(std::is_same_v<decltype(funptr), int(*)(int, int)>, "This succeeds");

This is useful for auto-type-deduction.

And it is useful for using lambdas with c-apis, where this can help to express, that the function should be captureless and no other programmer accedentially adds a capture:

Here an example with GLFW:

glfwSetKeyCallback(window, +[](GLFWwindow* w, int key, int scancode, int action, int mods) { /*...*/ });

Of course, you can express this by explicitly use a cast with GLFWkeyfun in this case, but you do not always want to look for the typedefs nor want to type the function type inline.

cmdlp
Автор

Additionally, std::function is not constexpr as, IIRC, it has a non-trivial destructor. If you switch from std::vector to std::array<int (*)(int, int), 2> and pass in the lambdas in an initializer list, the whole thing can be constexpr. I think that reduces to a mere 53 instructions in compiler explorer without optimization, and optimizes away everything if you do.

vorpal
Автор

One of my favorite usage of lamdas : giving function pointers to C libraries that use them a lot

Ybalrid
Автор

It's probably also worth noting that you don't need to rely on implicit type conversion here, but can instead explicitly tell the compiler to decay the lambda to a function pointer by prefixing it with a +. For example:

auto comparator = +[](const Person &lhs, const Person &rhs){ return lhs.name < rhs.name; };

The type of comparator here is already a function pointer rather than a compiler generated struct so there's no need to rely on an implicit conversion. It's perhaps not much help here since you still need to specify the type in the set anyway but worth noting for completeness.

grahampitt
Автор

Is there a way to define a function pointer with the keyword "using" if the lambda is capturing something like: auto l = [x](int i, int j){ return i + j + x; }; or even auto l = [&](int i, int j){ return i + j + x; }; ?

mocloun
Автор

Hi Jason, I have a requirement where I want to use Lambda to store lots of Qt Signals, for example &QPushButton::clicked, gives the address of the "clicked" signal. Qt has several overloaded connect methods that allow the developer to take different types of signal and connect them to slots with the same prototype. What I want to do is have a new connect method that is capable of connecting any signal with any prototype to a Lambda slot. This isn't currently possible, can you help to achieve this?

SimonPlatten
Автор

It would be interesting to see if you could give a non-std::functional solution for lambdas with states(closure) at least some small talk about it.

SimplySpiceIt
Автор

How big ist the difference between and capturing lambda and a function is it not in some ways only a function that takes all the things that are in scope so as arguments?

platin
Автор

I think it's time to cover the grate quick-bench.com website.

dvirtz