简体   繁体   中英

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>& .

To get it to work again, I have to introduce a const_cast<std::shared_ptr<Message>&> in the call to the handler.

Where is the const-ness introduced?

Thanks

psmg is captured by value, so it is only read only inside closure. If you would it to be modifible (because handler can do this getting shared_ptr by reference) you have to add mutable to lambda:

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

Live demo based on 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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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