这个 lambda 捕获参数中的 const-ness 是在哪里引入的?
Posted
技术标签:
【中文标题】这个 lambda 捕获参数中的 const-ness 是在哪里引入的?【英文标题】:where is the const-ness in this lambda capture argument introduced? 【发布时间】:2021-11-06 09:24:02 【问题描述】:这段代码编译正确。
#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 是在哪里引入的?
谢谢
【问题讨论】:
【参考方案1】:psmg
是按值捕获的,所以它在闭包内部是只读的。如果你需要它是可修改的(因为 handler
需要它)你必须将 mutable
添加到 lambda:
[pmsg](auto err, auto nbytes) mutable handler(pmsg, err, nbytes); );
Live demo based on BoostAsio
pmsg
被值捕获时,允许编译器进行一次隐式转换,所以从pmsg
创建临时shared_ptr
实例并传递给handler
,但临时对象不能绑定到左值引用(它可以与 const lvalue ref 一起使用)。
【讨论】:
以上是关于这个 lambda 捕获参数中的 const-ness 是在哪里引入的?的主要内容,如果未能解决你的问题,请参考以下文章