简体   繁体   English

这个 lambda 捕获参数中的常量性在哪里引入?

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

This code compiles correctly.此代码正确编译。

#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); });
}

However, when I add a reference to the first argument of the handler function但是,当我添加对处理程序函数的第一个参数的引用时

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

the code no longer compiles, complaining that I am trying to convert pmsg from a const std::shared_ptr<Message>& to a std::shared_ptr<Message>& .代码不再编译,抱怨我试图将 pmsg 从const std::shared_ptr<Message>&转换为std::shared_ptr<Message>&

To get it to work again, I have to introduce a const_cast<std::shared_ptr<Message>&> in the call to the handler.为了让它再次工作,我必须在对处理程序的调用中引入一个const_cast<std::shared_ptr<Message>&>

Where is the const-ness introduced? const-ness 在哪里引入?

Thanks谢谢

psmg is captured by value, so it is only read only inside closure. psmg是按值捕获的,因此它只能在闭包内读取。 If you would it to be modifible (because handler can do this getting shared_ptr by reference) you have to add mutable to lambda:如果您希望它是可修改的(因为handler可以通过引用获取shared_ptr来做到这一点),您必须将mutable添加到 lambda:

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

Live demo based on BoostAsio基于 BoostAsio 的现场演示


When pmsg is capture by value, the compiler is allowed to make one implicit conversion, so from pmsg is created temporary shared_ptr instance and passed to handler , but temporary object cannot be bound to Lvalue reference (it could be work with const lvalue ref).pmsg按值捕获时,允许编译器进行一次隐式转换,因此从pmsg创建临时shared_ptr实例并传递给handler ,但临时对象不能绑定到左值引用(它可以与 const左值引用一起使用)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM