C++ Weekly - Ep 332 - C++ Lambda vs std::function vs Function Pointer

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

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

The way I understand it is:
- if you're just passing a callable somewhere use a lambda (pass it as a generic callable type)
- if you have to store the callable object or its implementation depends on runtime information then:
- if the callable is stateless, use a function pointer
- if the callable has state, then use a std::function

And since requiring your objects to be stateless is a big limitation, function pointers are almost never used except when you really need good performance is some hot code and you'd sacrifice flexibility to gain speed.

zamf
Автор

Your english is clear and not complicated, thanks for all you did

talhaabus
Автор

For MSVC people that look into this make sure you use visual studio 17.2. Before it wasn't sometime inlining std::function. I believe this fixed it LWG-2774 2098 std::function construction vs assignment.
And for performance, from my own micro benchmark, calling a lambda, a function pointer and a std::function, is as performant to calling a corresponding free function of member function.

monamimani
Автор

Great episode. Would be nice to also contrast this with "passing a lambda by T&& or by value".

oschonrock
Автор

RISC-V has an extremely reduced instruction set, I would not be surprised if assigning to register and adding a value to "zero" and assigning the result to register would produce the same op-code. That is one of the purpose of having hard-coded register that is always zero, you can throw away a lot of special case op-codes.

Автор

Is it accurate to say 'a lambda is just an anonymous class with an operator() overload. Captured parameters are class members. The constructor initializes them from the capture expression. The lambda itself is the operator() overload. The end result is an object. No different than any other object, as far as objects in C++ go. '?Thanks Jason. I've learned a lot.

thestarinthesky_
Автор

I'm all about RISC-V, but I'm surprised you're using it for a demonstration on C++ weekly. Why choose that architecture?

Omnifarious
Автор

Also something that I think is interesting that you can't do with function pointers is using std::bind to bind an instantiated object member function to a std::function not to mention the added flexibility of std::placeholders.

irrationalnumbers
Автор

Think a big issue is that std::function does heap allocation (it has to because it copies the guts of the callable and the arguments), but if your return types and arguments are sufficiently small then maybe std::move_only_function or SG14 inplace_function might be more efficient.

willwu
Автор

14:46 I would also argue that the overhead in this case is inconsequential. If you're running an expensive operation but it's cycling at human speeds, the overhead is most likely going to be meaningless. If I'm playing like an RPG or something most likely I'm only going through 2-4 tiles per second maximum, so your window for extra overhead is in the hundreds of milliseconds. Optimization where it doesn't need to be optimized IMO.

BigPapaMitchell
Автор

li x, y is just a psuedo instruction for addi x, zero, y so the two outputs are equivalent.

niklassheth
Автор

`struct Location` can be eliminated and replaced with a concept at the site of use

shiretu
Автор

I hope someday they add a way to provide an allocator for std::function, since currently it can do its own secretive allocations that you have no control over.

N....
Автор

I was using std::function for a scope_guard but I ended up just using a template that takes in a lambda. I was getting exceptions and crashes I couldn't find out why. I'm only storing one function in my scope_guard so std::function was overkill. I couldn't use a function pointer, because I needed to capture some values.

Sebanisu
Автор

I'd be interested to see std::move_only_function in the mix as well and maybe comparisons with things like std::bind_front (though that is starting to get out of scope of this talk).

oracleoftroy
Автор

Not sure if I get this right, if optimizer does not optimize things,
function pointer is the fastest,
lambda is slower than function pointer,
std::function is the slowest one?

By using std::function you are trading speed for flaxibility.

openroomxyz
Автор

Does anyone know by any chance whether this channel has videos regarding standard library (smart pointers, containers, etc) in all the details? I'd like to learn more about its internals and peculiarities.

Btw, great video. Enjoyed it a lot.

JohnDoe-vfmt
Автор

Thank you very much, Jason, for providing us with yet another excellent episode! There’s one minor issue I would have, though. At around 6:18 you say „... so the lambda is a function...“. Well, no. A lambda is an anonymous class, or an object thereof. I‘m pretty sure you meant to say it that way 😉 But given the episode title, I wanted to point that out. This is a misconception that I really encounter often with my colleagues.

hagenmuller
Автор

I wouldn't necessary say std::function has an “overhead, ” I mean, you could use a pointer, but also if you don't know if the pointing position is valid (A.K.A. not nullptr), now you need to check that and you get the “overhead” back which is very small to begin with. Personally I'll always prefer a thown exception I can catch than a segmentation fault.

fcolecumberri
Автор

Any opinions on implementing callables via templates as T type? IIRC Boost.Asio uses it a lot for the async callback handlers. The downside is that the expected signature of the callable is poorly documented.

sledgex