luk32
luk32

Reputation: 16070

Is it possible to pass a lambda with captured non-copyable (moved) value?

I am trying to make a callable object, which essentially has a bound unique_ptr inside. I've read How to capture a unique_ptr into a lambda expression?

But I cannot pass the lambda further. The below code fails to compile indicating that copying unique_ptr is taking place. I don't quite understand why would it try to copy the unique_ptr.

#include <iostream>
#include <memory>
#include <functional>

using namespace std;

void f(std::function<void(int)> unary) {
    unary(42);
    unary(1337);
}

struct A{
    void woof(int i) {cout<< "woof " << i << "\n";}
};

int main(){
    auto another_unique = make_unique<A>();
    auto bound_p = [ p = move(another_unique) ] (int i) {p->woof(i);};
    bound_p(5);
    f( bound_p ); // does not compute
}

I've also tried defining lambda inline within the call to f, so that it would be a temporary object, and it could be moved into f. But the error was the same.

Is it possible to bind/wrap such object into callables and pass those around?

My use case hinges on unique_ptr, but I suspect any object with deleted copy c'tor will exhibit the same problem. If I am wrong then please tell me or edit the topic to be less general.

Upvotes: 3

Views: 1356

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473537

You cannot put any move-only type in std::function. That class requires the type to be copyable.

A better way to handle this would be to make f a template which will call the given parameter, rather than using the type-erased std::function. function should be used for cases where you want to keep a copy of the functor around, not when you just want to call it.

Upvotes: 7

Related Questions