//------------------------------------------------------------------------------
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
.
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.
std::function
requires functors to be copyable.
This is an arbitrary design decision. Possible alternatives could be:
std::function
causes a crash/exception.std::function
s 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.
It's a bug in Visual Studio. It attempts to ellide a copy (when actually it should be trying to ellide a move), which requires an accessible copy constructor. The best solution is simply to declare the copy constructor/assignment operator and never define them. The class will still be non-copyable but the code will compile, because VS will never attempt to actually call the copy constructor.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.