2016-11-22 60 views
4

我已經看過如何聲明向量函數(請參閱calling a function from a vector)。如何聲明函數向量(lambdas)

但是,這回答用戶指針。如何使用現代C++中的新語法創建函數/ lambdas的向量?

使用新語法通常的功能的例子使用自動:

auto f = [] (std::string msg) -> void { 
    std::cout << msg << std::endl; 
}; 

什麼是f的實際類型?所以我可以聲明這種類型的矢量?

非常感謝你的幫助

+2

「*什麼是實際的類型F *?」 無法命名。 「*所以我可以聲明這種類型的向量?」是的,但它不會幫助,因爲lambdas不是默認構造的。 'std :: vector >'可能適合你的目的。 – ildjarn

+2

如果lambda沒有關閉,你實際上仍然可以使用指針,btw – vu1p3n0x

+1

如果你不需要一個向量(即如果在編譯時已知實際lambda表達式),你可以創建一個lambdas的std :: tuple。 – dats

回答

10

使用std::function與相應類型:

std::vector<std::function<void(void)>> vec; 
vec.push_back([]()->void{}); 

你的情況,這將是std::function<void(std::string)>

確切類型的λ的是每標準([expr.prim.lambda]/3)無意義:

的類型λ-表達的(也是封閉的對象的類型)是一種獨特的,無名的非工會類類型

+0

謝謝。這正是我所期待的。 – dmg

+4

另一種選擇是使用函數指針,如果lambda沒有捕獲。 – rubenvb

7

什麼是f實際類型?所以我可以聲明這種類型的矢量?

f的類型只能使用auto來推導。您可以使用

std::vector<decltype(f)> v; 

聲明此類型的vector然而,它並不是非常有用。看起來驚人相似的Lambda函數有不同的類型。更糟糕的是,具有相同主體的lambda函數也有不同的類型。

auto f = [] (std::string msg) -> void { 
    std::cout << msg << std::endl; 
}; 

auto g = [] (std::string msg) -> void { 
    std::cout << msg << std::endl; 
}; 

auto h = [] (std::string msg) -> void { 
    std::cout << msg << '+' << msg << std::endl; 
}; 

鑑於上述功能,您不能使用

std::vector<decltype(f)> v; 
v.push_back(f); // OK 
v.push_back(g); // Not OK 
v.push_back(h); // Not OK 

你最好的選擇是創建std::functionstd::vector秒。您可以將該lambda函數添加到該std::vector。鑑於fg上述定義,你可以使用:

std::vector<std::function<void(std::string)>> v; 
v.push_back(f); 
v.push_back(g); 
v.push_back(h); 
0

如前所述每次申報拉姆達具有即便有看似相同的簽名獨特的背景特定的類型。這就是爲什麼lambda只有理論價值的原因 - 你最多可以在那裏推一個lambda ...你有兩種選擇 - 你可以從其他答案中提出方法,並將lambda存儲在類型擦除std::function中,然後將它們放入向量中,或者將你的lambda放入一個「容器」中,以收集除lambda之外的每個元素的類型對象本身 - std::tuple

auto t = std::make_tuple([](){ std::cout<<"First lambda" << std::endl; }, 
         [](){ std::cout<<"Second lambda"<< std::endl; }, 
         [](){ std::cout<<"Third lambda" << std::endl; }); 

,並在編譯時得到適當的λ:

std::get<0>(t)(); // the value in get must be known at compile time! 
        // otherwise compiler won't be able to establish type 
        // of lambda and the whole point of using tuple is lost 

[live demo]