Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ capture move initialized is const?

Tags:

c++

lambda

c++14

I am trying to move a local variable into the capture of 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();
}

When I compile I get this.

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

I was expecting the captured value to be none const.

like image 277
Martin York Avatar asked Jun 08 '16 05:06

Martin York


1 Answers

You could use mutable:

mutable - allows body to modify the parameters captured by copy, and to call their non-const member functions

Unless the keyword mutable was used in the lambda-expression, the function-call operator is const-qualified and the objects that were captured by copy are non-modifiable from inside this operator().

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

It's worth noting that this allows to modify on the object captured by copy, which has nothing to do with the original object.

like image 79
songyuanyao Avatar answered Sep 22 '22 12:09

songyuanyao