我試圖構建一個lambda包含一些前/後操作的輸入函數。變量在調用lambda之前被破壞
- 我的代碼工作正常,並且如果我嘗試包裝常規函數/ lambda,則前/後操作會正確調用。但是,當我嘗試將我的裝飾lambda應用於它之前生成的函數時,我的程序在抱怨內部函數在某個時候被釋放(這由valgrind確認)後崩潰。
令我百思不解的是,碰撞依賴於編譯:代碼工作完全正常與Xcode 6 clang
(基於clang-3.6
),但使用clang++-3.6
和g++4.8.4
在Linux上崩潰。
我做了一個小程序,再現行爲:
#include <iostream>
#include <string>
#include <functional>
using namespace std;
typedef function<void(void)> NestedFn;
int main()
{
// Create a cfunction
auto lambdaFactory = [&](string title, NestedFn nestedFunc)
{
// title is copied to the new lambda
return [&, title]() {
cerr << "------------ START -----------" << endl;
cerr << "Inside: " << title << endl;
nestedFunc();
cerr << "------------- END ------------" << endl;
};
}
auto l1 = lambdaFactory("1", []() { cerr << "\tNest (1)" << endl; });
auto l2 = lambdaFactory("2", []() { cerr << "\tNest (2)" << endl; });
l1(); // Works ok, displays, START, 1, END
l2(); // Same here
auto dobble = lambdaFactory("Dobble", l1);
dobble(); // Display START, Inside Dobble, START,
// then crashes when trying to execute nestedFunc(), ie l1()
}
我是怎麼弄錯的可變範圍管理?這個程序不是使用蘋果的LLVM崩潰嗎?
編輯
爲了記錄在案,這裏是T.C.建議修正後的正確lambdaFactory
:
auto lambdaFactory = [&](string title, NestedFn nestedFunc)
{
return [&, title, nestedFunc]() {
cerr << "------------ START -----------" << endl;
cerr << "Inside: " << title << endl;
nestedFunc();
cerr << "------------- END ------------" << endl;
};
};
的問題是,'lambdaFactory'的參數是按值傳遞,因此如果要返回lambda,則必須通過值捕獲它們。否則,你會有一個懸而未決的引用,因爲函數參數一旦返回就會超出範圍。 –