【发布时间】:2012-12-14 04:45:55
【问题描述】:
我从 Objective-C 的背景来到 C++11,我正在努力接受的一件事是 C++11 lambda 与 Objective-C“块”的不同捕获语义。 (请参阅here 进行比较)。
在 Objective-C 中,与 C++ 类似,如果您引用成员变量,则隐式捕获 self/this 指针。但是因为 Objective-C 中的所有对象都是有效的“共享指针”,使用 C++ 术语,你可以这样做:
doSomethingAsynchronously(^{
someMember_ = 42;
});
... 并且您可以保证在块执行时,您正在访问其成员的对象将是活动的。你不必考虑它。 C++ 中的等价物似乎是这样的:
// I'm assuming here that `this` derives from std::enable_shared_from_this and
// is already owned by some shared_ptr.
auto strongThis = shared_from_this();
doSomethingAsynchronously([strongThis, this] {
someMember_ = 42; // safe, as the lambda holds a reference to this
// via shared_ptr.
});
这里,除了this指针之外,你需要记住捕获shared_ptr。有没有一些不易出错的方法来实现这一点?
【问题讨论】:
-
“你不必考虑它。”开始考虑它。它可以带来更好的设计。
-
@Pubby 但问题是,使用块的轻松性使得它们对于 Obj-C 世界中的一次性异步任务如此有用且如此普遍。如果他们有 C++11 语义,并且你不得不问自己“这个对象会活着吗,这个对象会不会活着,这个对象会不会活着......”,我想很多人都会想说“去死吧,我会同步做的。”
-
从
this创建共享指针并不能保证它仍然存在,除非对象本身已经由共享指针拥有并且您正在复制它。创建一个新的共享指针(通过new shared_ptr<T>(this)或make_shared<T>(this))只会用于双重删除,除非内存会泄漏。那么,就您而言,如果此时不创建共享指针,this将如何被删除? -
@NickHutchinson:问题是所有权很重要。例如,查找 Rust -> 由开明的人创建的新语言 -> 所有权是 explicit。向用户隐藏所有权问题会鼓励她不要去想它,很快就会出现空间泄漏和臃肿的内存“我看不出有什么好的理由”。
-
@MSalters 如果没有参数,括号可以省略。 (所以
[]{}是最短的 lambda)
标签: c++ c++11 lambda shared-ptr