可以优化按值捕获的lambda吗?

时间:2018-08-06 17:22:10

标签: c++ boost lambda boost-asio lifetime

我目前正在为项目使用boost :: asio,并且必须将缓冲区发送到远程端点。我当前的数据发送算法如下:

void send_the_data(DataElement const& data)
{
    auto databuf = make_shared<std::vector<uint8_t>>(data.to_bytes());

    // lambda object holds a reference to the data to prevent early destruction. 
    asio::async_write(this->sock,
        asio::buffer(databuf),
        transfer_all(),
        [this, databuf](size_t bt, boost::system::error_code const& ec)
    {
        if(ec) this->handle_error(ec);
        else this->do_the_next_thing();

        assert(bt = databuf->size());
        // the destructor of this lambda should clean up the data buffer here,
        // after it has been handled. 
    });

}

我的逻辑是,shared_ptr的lambda捕获将防止销毁它,直到完成async_write之后,然后在执行处理程序后正确清理缓冲区。

但是,我很好奇,如果在lambda主体中没有对变量的引用,那么主要的编译器或标准是否允许捕获该变量,这将导致不确定的行为(由于可能会在async_write调用中访问悬空指针),或者该标准保证不会遗漏所有值捕获。

1 个答案:

答案 0 :(得分:5)

尽管[expr.prim.lambda] §2在理论上允许编译器优化闭包类型,但这种优化仅在 as-if规则下允许。因此,编译器可以优化关闭类型中的未引用数据,但仍然必须产生与各个成员的构造/破坏相关的任何副作用。

[expr.prim.lambda] §10指定为每个显式捕获创建一个闭包类型的成员。 [expr.prim.lambda] §15指定如何初始化。基于此,我想说 不允许编译器优化您的shared_ptr