【问题标题】:C++ capture move initialized is const?C++ 捕获移动初始化是 const 吗?
【发布时间】:2016-10-08 05:04:13
【问题描述】:

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

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

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

我希望捕获的值不是 const。

【问题讨论】:

  • mutable放在[data = std::move(data)]() /*here*/ {之后
  • 或者通过引用捕获它:[&amp;data]() { data.doWork(); }
  • @PiotrSkotnicki 为什么这里不允许使用初始化程序?
  • @PiotrSkotnicki 是否允许作为 init-capture?实际上标准中并没有提到这样的初始化,而它使用x = std::move(x) like 语句作为示例,但我猜它是允许的。
  • 现在我认为是允许的

标签: c++ lambda c++14


【解决方案1】:

你可以使用mutable:

可变 - 允许body修改copy捕获的参数,并调用它们的非常量成员函数

除非在 lambda 表达式中使用关键字 mutable,否则 函数调用运算符是 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();
    }
);

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

【讨论】:

  • 这允许副本是可变的,不会修改原始的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 2010-09-29
  • 1970-01-01
  • 2010-09-14
  • 2015-11-18
  • 1970-01-01
相关资源
最近更新 更多