我一直在玩C++ 11中的一些新功能,並試圖編寫下面的程序,期望它不起作用。出乎我的意料,它(海合會4.6.1在Linux x86與「STD = C++ 0x」爲標誌):C++ Lambda,捕獲,智能Ptrs和堆棧:爲什麼這樣工作?
#include <functional>
#include <iostream>
#include <memory>
std::function<int()> count_up_in_2s(const int from) {
std::shared_ptr<int> from_ref(new int(from));
return [from_ref]() { return *from_ref += 2; };
}
int main() {
auto iter_1 = count_up_in_2s(5);
auto iter_2 = count_up_in_2s(10);
for (size_t i = 1; i <= 10; i++)
std::cout << iter_1() << '\t' << iter_2() << '\n'
;
}
我期待「from_ref」被刪除時的每一次執行返回的lambda運行。這是我的推理:一旦運行了count_up_in_2s,from_ref就會彈出堆棧,但是因爲返回的lambda不是直接運行的,因爲它返回了,所以在一段短暫的時間內沒有另一個引用,直到相同的引用爲止當lambda實際運行時推回,所以不應該shared_ptr的引用計數爲零,然後刪除數據?
除非C++ 11的lambda捕獲比我給它的功勞更聰明,如果是這樣,我會很高興。如果是這種情況,只要/ something /正在處理動態分配的內存,我是否可以假設C++ 11的變量捕獲將允許所有的詞法範圍/封閉技巧和la Lisp?我能否假設所有捕獲的引用都會一直存在,直到lambda本身被刪除,從而允許我以上述方式使用smart_ptrs?
如果這是因爲我認爲是這樣,這是否意味着C++ 11允許表達式高階編程?如果是這樣,我認爲C++ 11委員會做了出色的工作=)
所以我是對的理解是,性病::函數對象本身在整個實例的持續時間存儲捕捉值
你的推理作品?而通過存儲這個引用,shared_ptr引用計數永遠不會達到0?啊,我明白了。多麼優雅。 – Louis 2011-12-19 04:19:33
@Louis不,不是函數對象,而是lambda。 'std :: function'不知道lambdas的捕獲。 – 2011-12-19 04:23:14
因此,捕獲和存儲引用被視爲一種特殊情況,而不是作爲std :: function實例中的成員存儲,比如說。謝謝。 – Louis 2011-12-19 04:24:05