可以优化按值捕获的 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 规则下进行。因此,编译器可以优化闭包类型中未引用的数据,但它仍然必须产生与各自成员的构造/破坏相关的任何副作用。
[expr.prim.lambda] §10 指定对于每个显式捕获,将创建一个闭包类型的成员。[expr.prim.lambda] §15 指定了它的初始化方式。基于此,我会说编译器不允许优化您的shared_ptr
。
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 空基优化子对象的地址
- 可组合的lambda/std::函数与std::可选
- 关闭||运算符优化
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 返回值优化:显式移动还是隐式
- 如何将lambda作为模板类的成员函数参数
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 人脸跟踪arduino代码的优化
- 在 lambda 捕获中声明的变量的类型推导
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- C++将 lambda 函数另存为成员变量,而不使用函数指针进行优化
- 可以优化按值捕获的 lambda 吗?
- C++:是否可以优化未使用的 lambda 显式捕获
- c++编译器会对lambda闭包执行编译时优化吗?
- 在 中全局引用捕获 lambda C++抑制别名优化