怎麼正確書寫C++高階函數?

代碼如下,編譯沒錯,運行在最後一行掛掉。

int main(){

std::function&< std::function& ( std::function& ) &>

f2=[](std::function& f1)

{

std::function& c= [](int param)

{

return f1(param)*param;

};

return c;

};

std::function& f =[](int a){ return a*5;};

std::function& f1;

std::cout&<&<1;

f1=f2(f);

std::cout&<&<1;

std::cout&<&

}


你有一個地方不應該引用捕獲,那就是那個高階函數返回lambda的時候

引用捕獲的是函數的局部參數,lambda返回到外面去,引用就失效了

所以記住一條規則,返回到外面的lambda,一律用值捕獲

另外代碼本身也有冗餘,很多地方直接用lambda就好,沒必要用function包一層

#include &
#include &
int main(){
auto f2 = [](auto f1) { //不需要捕獲的地方不要無腦寫
return [=](int param) { //這裡應該值捕獲,因為引用捕獲出了函數體之外就失效了
return f1(param)*param;
};
};

auto f = [](int a){ return a*5;}; //不需要捕獲的地方不要無腦寫

std::cout &<&< 1; auto f1 = f2(f); std::cout &<&< 1; std::cout &<&< f1(1); }

需要C++14


這樣可以嗎?

#include &
#include &
using namespace std;
int main()
{
std::function&(std::function&)&>
f2 = [](std::function& f1)
{
std::function& c = [=](int param) {
return f1(param) * param;
};
return c;
};
std::function& f = [](int a) { return a * 5; };

std::function& f1;
std::cout &<&< 1; f1 = f2(f); std::cout &<&< 1; if(f2) std::cout &<&< f1(1); }


C++14 開始按孫明琦菊苣的寫法就行了。

C++11 的話似乎還是要用 std::function 包一下:

#include &
#include &

int main(){
auto f2=[](const std::function& f1)
{
return [=](int param)
{
return f1(param)*param;
};
};

std::function& f=[](int a){ return a*5;};

auto f1=f2(f);
std::cout&<&

這裡 f2 的參數直接傳值也可以。

C++14 版本就這個例子來說 f2 參數用傳值更適合。


這個確實是因為用了引用捕獲,在

std::function&< std::function& ( std::function& ) &>
f2=[](std::function& f1)
{
std::function& c= [](int param)
{

return f1(param)*param;

};
return c;
};

這裡,賦給f2的lambda表達式傳入的參數是f1,類型不是引用,是值傳遞,因而在

return f1(param)*param;

這裡返回了一個局部變數。故而報錯。

解決方法之一是這麼寫

std::function&< std::function&(std::function&) &>
f2 = [](std::function& f1)
{
std::function& c = [](int param)
{

return f1(param)*param;

};
return c;
};

注意f2的類型也要有所改變,這或許是題主auto可過的原因,或者如同@kedixa那樣,局部變數c的lambda改為值捕獲。


推薦閱讀:

你怎麼看 C++11(新的 C++ 標準)裡面的變化?
我們需不需要跟進C++11/14?
double 和 long double 有哪些區別?
C++ 11會帶來什麼影響?

TAG:C | 函數式編程 | C標準 |