双重检查锁定模式 - 在传递给 call_once 的 lambda 中捕获
Posted
技术标签:
【中文标题】双重检查锁定模式 - 在传递给 call_once 的 lambda 中捕获【英文标题】:Double-check lock pattern - capture in lambda passed to call_once 【发布时间】:2018-07-15 07:31:53 【问题描述】:我正在观看 Herb Sutter 的 CppCon 2014 谈论无锁编程。
在handout page 7,我们有以下代码:
static unique_ptr<widget> widget::instance;
static std::once_flag widget::create;
widget& widget::get_instance()
std::call_once( create, [=] instance = make_unique<widget>(); );
return *instance;
我的问题:为什么这里使用[=]
捕获,而不是[&]
(或者可能只是[]
?)
cppreference 说:
[=]
通过副本捕获 lambda 主体中使用的所有自动变量,如果存在则通过引用捕获当前对象
但我们没有任何自动变量,也不需要当前对象。
【问题讨论】:
我什至会问“而不是[]
”。确实看起来很奇怪。
当然,这显然也是非真实代码。下一行的return
无论如何都不会编译。
我认为是错误的,也需要return *instance;
@hegel5000:不一定。你可以“蚕食”你的 equals 捕获的局部变量,就像你可以对函数使用按值复制的参数一样(例如,多次推进迭代器)。
我想说的是,这是一个完全未经测试的 sn-p,它只是为了说明一个特定的事情而编写的(call_once
的使用),所以尝试没有多大意义过度解读细节。
【参考方案1】:
这里不需要 capture-default。 []
会很好。
正如我在 cmets 中所写,这是一个未经测试的 sn-p,用于说明完全不相关的事物(即 call_once
)。尝试过多地阅读它没有多大意义。
也就是说,就“为适合幻灯片而编写的未经测试的 sn-p”类型而言,[=]
可能是最安全的默认lambda-introducer:[&]
可能导致数据竞争或悬空引用,如果您需要捕获,[]
将是错误的,并且显式捕获占用幻灯片上的宝贵空间 - 并且需要实际考虑捕获......
【讨论】:
以上是关于双重检查锁定模式 - 在传递给 call_once 的 lambda 中捕获的主要内容,如果未能解决你的问题,请参考以下文章