【问题标题】:where is the const-ness in this lambda capture argument introduced?这个 lambda 捕获参数中的 const-ness 是在哪里引入的?
【发布时间】: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&lt;Message&gt;&amp; 转换为 std::shared_ptr&lt;Message&gt;&amp;

要让它再次工作,我必须在对处理程序的调用中引入const_cast&lt;std::shared_ptr&lt;Message&gt;&amp;&gt;

const-ness 是在哪里引入的?

谢谢

【问题讨论】:

    标签: c++ lambda c++17 asio


    【解决方案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 一起使用)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-15
      • 2015-03-13
      • 2011-04-10
      • 1970-01-01
      • 2019-08-03
      • 2018-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多