c ++ lambda捕获了这个概念

时间:2016-10-12 10:44:11

标签: c++11 lambda capture

使用C ++进行编程,也许我的思绪仍然停留在90年代,无法解决一些概念,请帮助我。

所以正在使用gtkmm开发,并遇到了一些多线程示例,就像这个

class ExampleWorker {

public:
    void do_work(ExampleWindow* caller);
private:
    mutable std::mutex m_Mutex;
};

ExampleWindow::ExampleWindow(){
    ExampleWorker m_Worker;
    std::thread* m_WorkerThread;

void ExampleWindow::on_start_button_clicked() {
    if (blablabla){
        blablabla
    } else {
        // Start a new worker thread.
        m_WorkerThread = new std::thread(/////////////lambda function
            [this]    // <==== let this this be "this-A"
            {
                m_Worker.do_work(this);     // let this this be "this-B"
            }///////////////end of lambda function /////////////
        );
    }

我无法理解的主要问题是lambda部分。所以首先,lambda概念对我来说是一个新概念,正在寻找&#34;捕获&#34;的概念。在C ++中但是没有找到太多,所以我最好的猜测是,在这种情况下,它允许我捕获&#34; &#34; [this]&#34;根据文档,返回的似乎是[this] captures the this pointer by value,指向作为线程指针的工作者的指针,因为工作程序包含互斥锁。

然而,我不明白的是,对我来说,&#34;这是B&#34;似乎表明&#34;这个&#34;将ExampleWindow对象本身传递给函数,由Worker类定义它应该将调用者传递给它;告诉&#34;这个A&#34;似乎能够引用工作线程本身。问题,这是否意味着在这种情况下lambda函数捕获[this]取代了正常的&#34;这个&#34;它将调用对象称为&#34; this-B&#34;?

关于lambda事情的更多内容,我一直努力理解的另一个例子来自boost asio。

//definition
void async_read_some(
const MutableBufferSequence & buffers,
ReadHandler handler);

// async_tcp_echo_server.cpp
class session  : public std::enable_shared_from_this<session>{
private:
  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) //<===this is where it is very troubling
        {
          if (!ec)
          {
            do_write(length);
          }
        });
  }

假设该部分是一个处理程序,它为什么,或者它是2个函数?它会调用this-&gt; do_write和self-&gt; do_write吗?他们有什么不同?在这种情况下,[this,self] / [this] / [self]之间究竟有什么区别?这是第一次/自我执行吗?

关于lambda的更多内容,它只是简化了预先c ++ 11中某些内容的语法吗?有什么等效的前c ++ 11?或者它是否提供新功能,例如访问函数中以前无法访问的某些变量?对不起,这似乎是微不足道的,但我想我通读了文档和其他一些在线文章并尝试过,但仍未能掌握整个概念。

1 个答案:

答案 0 :(得分:7)

当我像这样看着他们时,对我理解lambdas起初是有帮助的。

struct <closure>
{
    <something> operator()(<params>) const { ... <function>; }

    <init-capture-as-members>
};

所以

[someInt](double a, double b) { return 5; }

struct <closure>
{
    int operator()(double a, double b) const { return 5; }        
    int someInt;
};

捕获列表中的所有内容都像&#34;成员&#34;当你执行lambda时,你调用operator()

它更复杂(甚至有const和mutable等),但它只是一个简单的抽象。

现在针对您的具体问题:

this是指向您所在对象的指针。因此它不是指向std::thread对象的指针,而是指向ExampleWindow对象的指针。

捕获列表中的

this也有一种特殊情况。 当您将[this]添加到捕获列表时,您可以&#34;允许&#34; lambda调用当前对象的所有内容。它还允许您使用成员函数,而不使用this->作为前缀。

因此,您的通话do_write(...)可以被视为this->do_write(...)

self只是一个共享指针,因此它将被视为每个其他捕获的对象。您必须明确调用self->...才能对其执行任何操作。我假设在init-capture中需要这个,所以只要线程正在运行,对象就会保持活动状态。在init-capture中使用this不会增加引用次数,因此在没有它的情况下调用do_write时可能会意外删除该对象。