使用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?或者它是否提供新功能,例如访问函数中以前无法访问的某些变量?对不起,这似乎是微不足道的,但我想我通读了文档和其他一些在线文章并尝试过,但仍未能掌握整个概念。
答案 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
时可能会意外删除该对象。