这个 lambda 捕获参数中的 const-ness 在哪里引入?

where is the const-ness in this lambda capture argument introduced?

此代码编译正确。

#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 从 const std::shared_ptr<Message>& 转换为 std::shared_ptr<Message>&

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

哪里引入了const-ness?

谢谢

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

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

Live demo based on BoostAsio


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