2

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.

Community
  • 1
  • 1
luk32
  • 15,812
  • 38
  • 62

1 Answers1

7

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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • `unary` is supposed to be a callback, so I'd need something that I can store and then call. `f` is a mock for calling a stored callable. – luk32 May 12 '17 at 16:05
  • @luk32: Well, there's no move-only version of `std::function`. So your options are to remove the move-only type from your lambda. Or to write your own equivalent to `std::function`. – Nicol Bolas May 12 '17 at 16:07
  • A `view_function` has better meaning than plain template type BTW. Sad that `std::function` is used for that. – Jarod42 May 12 '17 at 16:29
  • @Jarod42: That wouldn't work for his needs, since he explicitly wants it to claim ownership of the callback, with a stored `unique_ptr` and everything. – Nicol Bolas May 12 '17 at 17:42
  • `f` doesn't have to take ownership, so using something like [function_view](http://stackoverflow.com/a/39087660/2684539) or [passing_functions_to_functions](https://vittorioromeo.info/index/blog/passing_functions_to_functions.html) should be enough. – Jarod42 May 12 '17 at 19:13
  • @Jarod42: As luk32 said, "*`f` is a mock for calling a stored callable.*" Don't take the example literally. – Nicol Bolas May 12 '17 at 19:18