可以优化 lambda 按值捕获吗?

Can lambda capture-by-value be optimized out?

我目前正在使用 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 调用中的悬垂指针),或者如果标准保证不会省略所有值捕获。

虽然 [expr.prim.lambda] §2 理论上允许编译器优化闭包类型,但这种优化仅在 as-if 规则 下才允许。因此,编译器可以从闭包类型中优化掉未引用的数据,但它仍然会产生与各个成员的 construction/destruction 相关的任何副作用。

[expr.prim.lambda] §10 specifies that for each explicit capture, a member of the closure type is created. [expr.prim.lambda] §15 指定它是如何初始化的。基于此,我会说编译器 不允许 优化你的 shared_ptr