gpt4 book ai didi

c++11 - c++ lambda 捕获这个概念

转载 作者:行者123 更新时间:2023-12-04 06:47:07 24 4
gpt4 key购买 nike

用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 概念对我来说很新,正在查找 C++ 中“捕获”的概念但没有找到太多,所以我最好的猜测是,在这种情况下,它允许我“捕获”“根据文档,返回的 [this]"似乎是 [this] 按值捕获 this 指针,指向 worker 的指针被转换为线程指针,因为 worker 包含互斥锁。

但是我不明白的是,对我来说,“this-B”似乎表明“this”正在将 ExampleWindow 对象本身传递给函数,正如它应该传递的 Worker 类所定义的那样它的调用者进入它;而“this-A”似乎能够指代工作线程本身。问题,这是否意味着 lambda 函数捕获 [this] 在这种情况下取​​代了正常的“this”,后者指的是“this-B”中的调用对象?

关于 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->do_write 和 self->do_write 吗?它们有何不同?在这种情况下,[this, self]/[this]/[self] 之间到底有什么区别?是第一个 this/self 被执行了吗?

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

最佳答案

对我来说,最初理解 lambda 对我这样看待它们很有帮助。

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;
};

捕获列表中的所有内容都像“成员”,当您执行 lambda 时,您调用 operator()

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


现在针对您的具体问题:

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

this在捕获列表中也有一种特例。当您添加 [this]在捕获列表中,您“允许”lambda 调用当前对象的所有内容。它还允许您在不使用 this-> 的情况下使用成员函数。虽然作为前缀。

所以你的电话do_write(...)可以看作是this->do_write(...)

self只是一个共享指针,所以它将像其他所有捕获的对象一样对待。您必须显式调用 self->...对它做任何事情。我假设这在 init-capture 中是必需的,因此只要线程运行,对象就会保持事件状态。仅使用 this在 init-capture 中不会增加引用计数,因此您可能会在调用 do_write 时意外删除该对象没有它。

关于c++11 - c++ lambda 捕获这个概念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39996625/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com