Closed espenkn closed 1 month ago
Typically you would use std::forward
instead of std::move
when you use &&
with a template parameter due to reference collapsing rules, but otherwise I don't see why this isn't working for you. Are you sure the issue isn't with where you're storing the lambda? For example, std::function
always requires the functor to be copyable even if it is never copied, consider upgrading to std::move_only_function
instead.
Typically you would use
std::forward
instead ofstd::move
when you use&&
with a template parameter due to reference collapsing rules, but otherwise I don't see why this isn't working for you. Are you sure the issue isn't with where you're storing the lambda? For example,std::function
always requires the functor to be copyable even if it is never copied, consider upgrading tostd::move_only_function
instead.
OMG, I think you are correct that it is passing the lambda that is the issue! Thank you so much for the reply, I now just need to find a suitable alternative for std::move_only_function
since i don't have it in my compiler.
I did not even know about the copy requirement on std::function and I have not heard about the new move_only_function. Thanks for enlightening me.
As for the episode idea, perhaps a show and tell of std::move_only_function is what i wanted instead, with also alternatives for us that don't have c++23 yet.
In a pinch you can wrap the lambda into a functor that is copyable, for example with std::shared_ptr
- not ideal but it works:
template<typename Lambda>
class shared_lambda
{
std::shared_ptr<Lambda> lambda;
public:
shared_lambda(Lambda&& lambda_) : lambda(std::make_shared<Lambda>(std::move(lambda_))) {}
decltype(auto) operator()(auto&&... args) noexcept(std::is_nothrow_invocable_v<Lambda, decltype(args)...>)
{
return std::invoke(*lambda, std::forward<decltype(args)>(args)...);
}
};
Thanks again @LB-- for your excellent help, it so much more appreciated than i can put into words.
I ended up in the end shimming this with a slightly modified version of this idea here https://stackoverflow.com/a/52358928/2642865 until I can get proper std-23, hopefully withing the near future.
To be honest that shim don't sit right with me, so I might drop it and just go for your wrapper instead :heart:
This comment thread plus #329 - I'm closing this issue I think. Create a new one if there's something else you want to discuss.
Channel "C++Weekly" episode request
Topics
Moving parameter packs into a lambda, is it possible?
Length
Probably short, comparable to the episode about Transforming Lambdas. I saw the trick using 'initialized lambda pack capture' or 'structured packing' or whatever the correct term is and want to do something like that with move.
So I know that I can move a template argument into a lambda, but I want a template that takes an parameter pack and moves it like:
Context for the example given here is for working with Java JNI and we want to create this function somewhere and perhaps even execute it on another thread so we can not have any dangling references and the wrapper types contains smart pointer and i would like to use an unique pointer. Is there a way to otherwise make this code so that we know we would have extended the lifetime so that we don't have any invalid references?
I can not get this to work (with my compiler) since it still insists on a copy. I have a working variant that's using copies with mutable types to emulate a move, but i really want the proper moves...
Hope you consider this since I can not figure out if there is a way to move a pack into lambdas and that would be neat.