23
//------------------------------------------------------------------------------
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.

4

3 回答 3

24

简短的回答是 C++11 规范要求您A必须CopyConstructiblestd::function.

长答案是存在此要求,因为std::function在构造函数中删除了仿函数的类型。为此,std::function必须通过虚函数访问仿函数的某些成员。其中包括调用运算符、复制构造函数和析构函数。并且由于这些是通过虚拟调用访问的,因此无论您是否实际使用std::function的复制构造函数、析构函数或调用运算符,它们都被“使用”。

于 2012-08-01T22:21:34.250 回答
0

std::function要求函子是可复制的。

这是一个任意的设计决定。可能的替代方案可能是:

  • 允许使用不可复制的仿函数,但尝试复制结果std::function会导致崩溃/异常。
  • 允许使用不可复制的函子,并且std::functions 本身始终是不可复制的。
  • ...

如果结果std::function被复制,则不可能只要求可复制性,因为它可以在不同的 TU(翻译单元)中复制。

所以,如果你问我,当前的行为是较小的邪恶。

于 2021-06-20T18:03:24.977 回答
-3

这是 Visual Studio 中的一个错误。它尝试省略一个副本(实际上它应该尝试省略一个移动),这需要一个可访问的复制构造函数。最好的解决方案是简单地声明复制构造函数/赋值运算符并且从不定义它们。该类仍然是不可复制的,但代码将编译,因为 VS 永远不会尝试实际调用复制构造函数。

于 2012-08-01T22:08:06.907 回答