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

Viewed 2727
//------------------------------------------------------------------------------
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.

3 Answers

std::function requires functors to be copyable.

This is an arbitrary design decision. Possible alternatives could be:

  • Non-copyable functors are allowed, but attempting to copy the resulting std::function causes a crash/exception.
  • Non-copyable functors are allowed, and std::functions themselves are always non-copyable.
  • ...

It's impossible to only require copyability if the resulting std::function is copied, because it can be copied in a different TU (translation unit).

So, if you ask me, the current behavior is the lesser evil.

Related