class Request { function<map<string,string>(const map<string,string>&)> oper; // operation map<string,string> values; // arguments map<string,string> results; // targets public: Request(const string& s); // parse and store request void execute() { [this]() { results=oper(values); } // do oper to values yielding results } };
成员总是被引用捕获。也就是说,
[this]
意味着 成员可以通过this
访问,而不是复制到lambda中。 很遗憾,[this]
和[=]
不兼容。这意味着 不谨慎使用会导致多线程程序中的竞争条件 (§42.4.6)。
答案 0 :(得分:2)
该竞争条件的先决条件是:
this
标识的对象在lambda的生命周期内由多个线程访问。通常,您希望最小化在多个线程之间共享的对象数量,因为它们是竞争条件的来源(有或没有lambdas)。并且,像往常一样,通过锁定来保护对this
对象的访问,可以使lambda使用安全。
答案 1 :(得分:2)
他试图明确表示捕获this
- 无论是隐式还是显式 - 都不会复制this
指定的对象。令人惊讶的是,像[=](){ return oper(values); }
这样的lambda正在捕获指向对象的指针,而不是捕获oper
和values
的副本。
隐式泄漏指针/引用并在多线程代码中传播它们是灾难性UB的一个秘诀。该标准没有定义具有数据竞争的程序的行为:多个线程可能同时访问内存位置(对象),其中至少有一个执行写入。