初始化C++捕获移动是常量

C++ capture move initialized is const?

本文关键字:常量 移动 C++ 初始化      更新时间:2023-10-16

我正在尝试将局部变量移动到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 << "Workn";
        }
};
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();
}

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

> 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();
            ^~~~

我期望捕获的值为无常量。

您可以使用可变:

可变 - 允许主体修改 copy 捕获的参数,并调用其非常量成员函数

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

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

值得注意的是,这允许对复制捕获的对象进行修改,这与原始对象无关。