Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't C++11 move a noncopyable functor to a std::function?

Tags:

//------------------------------------------------------------------------------ struct A {     A(){}     A(A&&){}     A& operator=(A&&){return *this;}     void operator()(){}  private:     A(const A&);     A& operator=(const A&);      int x; };  //------------------------------------------------------------------------------ int main() {     A a;     std::function<void()> func(std::move(a)); } 

'A::A' : cannot access private member declared in class 'A'

It seems like when I capture something by reference or const I can make a non-copyable lambda. However when I do that it actually works to give it to a std::function.

like image 942
David Avatar asked Aug 01 '12 22:08

David


People also ask

Can std :: function be copied?

You can recover the desired behavior by always using thread-local copies of the std::function because they'll each have an isolated copy of the state variables.

What is the point of std :: function?

Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.


1 Answers

The short answer is that the C++11 specification requires your A to be CopyConstructible to be used with std::function.

The long answer is this requirement exists because std::function erases the type of your functor within the constructor. To do this, std::function must access certain members of your functor via virtual functions. These include the call operator, the copy constructor and the destructor. And since these are accessed via a virtual call, they are "used" whether or not you actually use std::function's copy constructor, destructor or call operator.

like image 106
Howard Hinnant Avatar answered Sep 22 '22 15:09

Howard Hinnant