这个 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); });
当pmsg
按值捕获时,允许编译器进行一次隐式转换,因此从pmsg
创建临时shared_ptr
实例并传递给handler
, 但临时对象不能绑定到 Lvalue reference (它可以与 const lvalue ref 一起使用)。
此代码编译正确。
#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); });
当pmsg
按值捕获时,允许编译器进行一次隐式转换,因此从pmsg
创建临时shared_ptr
实例并传递给handler
, 但临时对象不能绑定到 Lvalue reference (它可以与 const lvalue ref 一起使用)。