Зачем захватывать это, а также общий-указатель на это в лямбдах?

В примерах Boost.asio С++ 11 есть фрагменты как показано ниже:

void do_read()
{
  auto self(shared_from_this());
  socket_.async_read_some(boost::asio::buffer(data_, max_length),
      [this, self](boost::system::error_code ec, std::size_t length)
      {
        if (!ec)
        {
          do_write(length);
        }
      });
}

Я понимаю, почему указатель self необходим для сохранения класса (см. этот вопрос), но я не понимаю, почему указатель this также захватывается. Разве это так, что автор может написать do_write(length) вместо self->do_write(length) или есть ли другая причина?

Ответы

Ответ 1

Без this, вы не можете вызывать методы класса из лямбда (например, do_write). Или переменные члена доступа. Конечно, вы могли бы написать self->do_write(), но он был менее элегантным и потенциально медленным (из-за участия shared_ptr).

Ответ 2

Ответ, поставленный там, является АБСОЛЮТНО неправильным! Вы не должны проходить оба! Вот как вы должны это сделать, основываясь на вашем коде, не проходя this:

void do_read()
{
  auto self(shared_from_this());
  socket_.async_read_some(boost::asio::buffer(data_, max_length),
      [self](boost::system::error_code ec, std::size_t length)
      {
        if (!ec)
        {
          self->do_write(length);
        }
      });
}

И на самом деле, вы должны использовать std::bind, а не lambdas для этого. Это сделает ваш код более компактным.