//------------------------------------------------------------------------------
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':无法访问在类'A'
中声明的私有成员似乎当我通过引用或const
捕获某些内容时,我可以创建一个不可复制的lambda。但是,当我这样做时,实际上可以将它赋予std::function
。
答案 0 :(得分:21)
简短的回答是,C ++ 11规范要求A
CopyConstructible
与std::function
一起使用。
答案很长,因为std::function
会删除构造函数中的仿函数类型,因此存在此要求。为此,std::function
必须通过虚函数访问函子的某些成员。这些包括调用运算符,复制构造函数和析构函数。由于这些是通过虚拟调用访问的,因此无论您是否实际使用std::function
的复制构造函数,析构函数或调用操作符,它们都会被“使用”。
答案 1 :(得分:0)
std::function
要求函子是可复制的。
这是一个随意的设计决定。可能的替代方案是:
std::function
会导致崩溃/异常。std::function
本身始终是不可复制的。如果复制结果 std::function
,不可能只要求可复制性,因为它可以在不同的 TU(翻译单元)中复制。
所以,如果你问我,目前的行为是较小的邪恶。
答案 2 :(得分:-1)
这是Visual Studio中的一个错误。它试图省略一个副本(实际上它应该试图进行移动),这需要一个可访问的复制构造函数。最好的解决方案是简单地声明复制构造函数/赋值运算符,而不是定义它们。该类仍然是不可复制的,但代码将编译,因为VS永远不会尝试实际调用复制构造函数。