C++ lambda捕获参数的const属性是在何处引入的?
const属性来源与解决方法
- 该const属性来自你定义的lambda表达式的默认特性:C++标准规定,未加
mutable修饰的lambda,它的调用运算符operator()默认是const修饰的。你在lambda中按值捕获了pmsg,这个变量会作为lambda对象的成员变量存在,在const修饰的operator()中访问所有值捕获的成员变量时,变量都会被带上const属性,所以你拿到的pmsg类型是const std::shared_ptr<Message>&,自然无法绑定到handler要求的非const左值引用参数上。 - 按值传递参数时不需要修改原对象,const对象的拷贝构造是合法的,所以参数改为值传递时编译可以正常通过。
正确解决方法(不推荐使用const_cast,极易引发未定义行为)
- 如果你的
handler函数内部不需要修改shared_ptr本身(比如不需要重置指针、修改引用计数等,仅修改它指向的Message对象是不需要修改shared_ptr本身的),直接将handler的第一个参数改为const引用即可:
void handler(const std::shared_ptr<Message>& pmsg, asio::error_code error, size_t nbytes);
- 如果确实需要在
handler内修改这个按值捕获的shared_ptr,给lambda添加mutable修饰,取消operator()的const属性:
asio::async_read(mysocket, asio::buffer(&pmsg->msg, sizeof(int)), [pmsg](auto err, auto nbytes) mutable { handler(pmsg, err, nbytes); });
内容的提问来源于stack exchange,提问作者Fabio
相关产品推荐
相关产品推荐

