2

I'm basically trying do do this:

using Type = SomeTypeThatIWantToMove;

std::promise<Type> promised_result;
std::future<Type> promised_future = promised_result.get_future();

using Callback = std::function<void()>;

Callback function_which_should_be_movable =
            [this, future_result(std::move(promised_future))]() mutable
{
    this->some_function(future_result.get());   // signature: void some_function(const Type&)
};

using ResultBuilder = std::function<Type(Callback&&)>;

// result_builder is of type ResultBuilder  
Type thingy = result_builder(std::move(function_which_should_be_movable));

MinGW tell me, that the Move-Constructor of function_which_should_be_movable is deleted, because the Copy-constructor of std::future is deleted. However, I don't see why the compiler would attempt to copy the future instead of moving it.

Jack Sabbath
  • 1,398
  • 2
  • 9
  • 12

1 Answers1

4

function_which_should_be_movable is of type std::function. According to cppreference:

template< class F > function( F f ); F must meet the requirements of Callable and CopyConstructible.

The lambda expression you try to use to construct an std::function object is not copyable, and hence the problem.

As to why std::function has this requirement, please see this question: Why the initializer of std::function has to be CopyConstructible? (which is asked exactly by myself). Simply put, the type erasure technique used by std::function will instantiate the copy-constructor of F. This happens regardless of whether you, the user of the std::function object, actually used this copy-constructor or not.

Community
  • 1
  • 1
Lingxi
  • 14,579
  • 2
  • 37
  • 93
  • In this case, what is the point of C++14's Lambda capture expressions? The idea is to allow something like this: std::unique_ptr ptr(new int(10)); auto lambda = [value = std::move(ptr)] {return *value;}; So why would I move something into a function object, if the function object itself gets stuck at its place forever, because the moved object disables copying or moving. – Jack Sabbath Apr 24 '15 at 12:36
  • Then you need something else than `std::function`. Something like it, but without type erasure. So you could avoid instantiating the copy-constructor by not using it. – Lingxi Apr 24 '15 at 12:41
  • Constructing the function object is not the problem, even if function_which_should_be_movable would not be copyable. I can construct it and call it in place. The error only occurs when I try to move the object. But again: I don't see why a deleted copy-constructor prevents me from moving the function. Where is the copy-constructor called in the move process? – Jack Sabbath Apr 24 '15 at 12:51
  • 1
    Constructing the function object is a problem. See http://coliru.stacked-crooked.com/a/3a20c84f4237fbeb. Constructing such a function object instantiates all its virtual member functions, and the copy-constructor of the supplied type is called in one of them. Virtual member functions will by no means be optimized out. – Lingxi Apr 24 '15 at 13:09