为什么C++ 11不能将不可复制的仿函数移动到std :: function?

Dav*_*vid 18 c++ lambda function c++11

//------------------------------------------------------------------------------
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));
}
Run Code Online (Sandbox Code Playgroud)

'A :: A':无法访问类'A'中声明的私有成员

似乎当我通过引用捕获某些东西时,或者const我可以制作一个不可复制的lambda.但是,当我这样做时,它实际上是为了给它一个std::function.

How*_*ant 21

简短的回答是,C++ 11规范要求你ACopyConstructible与其一起使用std::function.

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

  • 有关类型擦除的工作原理的说明,请参见http://stackoverflow.com/questions/6324694/type-erasure-in-c-how-boostshared-ptr-and-boostfunction-work.基类是std :: function的实现细节.派生类也是一个实现细节,但也在提供的仿函数上进行了模板化. (5认同)
  • @GManNickG:唯一的机会是,如果有一个附带的实施清楚地表明它可以通过所有现有的单元测试,并拥有足够友好的版权许可.我个人目前不知道如何创建这样的实现.但我喜欢这个行业的是我总是在学习新东西.:-) (2认同)