首页 > 解决方案 > 这个 lambda 捕获参数中的 const-ness 是在哪里引入的?

问题描述

此代码编译正确。

#include <asio.hpp>
#include <memory>
#include <iostream>

struct Message { int msg; };

// never mind global variables, just for the sake of making this a minimal example
extern asio::ip::tcp::socket mysocket;

void handler(std::shared_ptr<Message> pmsg, asio::error_code error, size_t nbytes);

void readMessage()
{
    std::shared_ptr<Message> pmsg{ new Message };
    asio::async_read(mysocket, asio::buffer(&pmsg->msg, sizeof(int)),
            [pmsg](auto err, auto nbytes) { handler(pmsg, err, nbytes); });
}

但是,当我添加对处理函数的第一个参数的引用时

void handler(std::shared_ptr<Message>& pmsg, asio::error_code error, size_t nbytes);

代码不再编译,抱怨我试图将 pmsg 从 a 转换const std::shared_ptr<Message>&为 a std::shared_ptr<Message>&

为了让它再次工作,我必须const_cast<std::shared_ptr<Message>&>在对处理程序的调用中引入 a 。

const-ness 是在哪里引入的?

谢谢

标签: c++lambdac++17asio

解决方案


psmg是按值捕获的,所以它在闭包内部是只读的。如果您需要它是可修改的(因为这是必需的handler),您必须添加mutable到 lambda:

[pmsg](auto err, auto nbytes) mutable { handler(pmsg, err, nbytes); });

基于 BoostAsio 的现场演示


pmsg按值捕获时,允许编译器进行一次隐式转换,因此 frompmsg被创建临时shared_ptr实例并传递给handler,但临时对象不能绑定到Lvalue 引用(它可以与 const lvalue ref 一起使用)。


推荐阅读