初始化的C++捕获移动是const吗?

Mar*_*ork 12 c++ lambda c++14

我试图将局部变量移动到lambda的捕获.

#include <thread>
#include <iostream>

// Moveable but not copyable object.
class WorkUnit
{
    public:
        WorkUnit(int)                               {}
        WorkUnit(WorkUnit&&)            noexcept    {}
        WorkUnit& operator=(WorkUnit&&) noexcept    {return *this;}
        WorkUnit(WorkUnit const&)                   = delete;
        WorkUnit& operator=(WorkUnit const&)        = delete;

        // Non const function.
        void doWork()
        {
            std::cerr << "Work\n";
        }
};

int main()
{
    WorkUnit    data(4);

    // Use C++14 generalized lambda capture.
    std::thread test([data{std::move(data)}]()
        {
            // here it is complaining the `data` is a const value.
            // Is there a way to capture this as a non const?
            data.doWork();
        }
    );
    test.join();
}
Run Code Online (Sandbox Code Playgroud)

当我编译时,我得到了这个.

> g++ -std=c++14 WU.cpp
Test.cpp:26:13: error: member function 'doWork' not viable: 'this' argument has type 'const WorkUnit',
      but function is not marked const
            data.doWork();
            ^~~~
Run Code Online (Sandbox Code Playgroud)

我期待捕获的值不是常量.

son*_*yao 12

你可以使用mutable:

mutable - 允许body修改copy复制的参数,并调用非const成员函数

除非mutable在lambda表达式中使用了关键字,否则函数调用运算符是const限定的,并且由副本捕获的对象在此内部是不可修改的operator().

std::thread test([data{std::move(data)}]() mutable
    {
        // the function-call operator is not const-qualified;
        // then data is modifiable now
        data.doWork();
    }
);
Run Code Online (Sandbox Code Playgroud)

值得注意的是,这允许修改由副本捕获的对象,这与原始对象无关.