为什么我不能在 C++11 中创建一个 lambda 向量(相同类型)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7477310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:01:18  来源:igfitidea点击:

Why can't I create a vector of lambdas (of the same type) in C++11?

c++vectorlambdac++11

提问by Nawaz

I was trying to create a vector of lambda, but failed:

我试图创建一个 lambda 向量,但失败了:

auto ignore = [&]() { return 10; };  //1
std::vector<decltype(ignore)> v;     //2
v.push_back([&]() { return 100; });  //3

Up to line #2, it compiles fine. But the line#3 gives compilation error:

直到第 2 行,它编译得很好。但是第 3 行给出了编译错误

error: no matching function for call to 'std::vector<main()::<lambda()>>::push_back(main()::<lambda()>)'

错误:没有用于调用“std::vector<main()::<lambda()>>::push_back(main()::<lambda()>)”的匹配函数

I don't want a vector of function pointers or vector of function objects. However, vector of function objects which encapsulate reallambda expressions, would work for me. Is this possible?

我不想要函数指针向量或函数对象向量。然而,封装真正的lambda 表达式的函数对象向量对我有用。这可能吗?

回答by Puppy

Every lambda has a different type—even if they have the same signature. You must use a run-time encapsulating container such as std::functionif you want to do something like that.

每个 lambda 都有不同的类型——即使它们有相同的签名。您必须使用运行时封装容器,例如,std::function如果您想做类似的事情。

e.g.:

例如:

std::vector<std::function<int()>> functors;
functors.push_back([&] { return 100; });
functors.push_back([&] { return  10; });

回答by R. Martinho Fernandes

All lambda expressions have a different type, even if they are identical character-by-character. You're pushing a lambda of a different type (because it's another expression) into the vector, and that obviously won't work.

所有 lambda 表达式都有不同的类型,即使它们是相同的。您将不同类型的 lambda(因为它是另一个表达式)推入向量中,这显然行不通。

One solutionis to make a vector of std::function<int()>instead.

一种解决方案是制作一个向量std::function<int()>

auto ignore = [&]() { return 10; };
std::vector<std::function<int()>> v;
v.push_back(ignore);
v.push_back([&]() { return 100; });

On another note, it's not a good idea to use [&]when you're not capturing anything.

另一方面,[&]当你没有捕捉任何东西时使用它不是一个好主意。

回答by Luc Danton

While what others have said is relevant, it is still possible to declare and use a vector of lambda, although it's not very useful:

虽然其他人所说的是相关的,但仍然可以声明和使用 lambda 向量,尽管它不是很有用:

auto lambda = [] { return 10; };
std::vector<decltype(lambda)> vec;
vec.push_back(lambda);

So, you can store any number of lambdas in there, so long as it's a copy/move of lambda!

因此,您可以在其中存储任意数量的 lambda,只要它是lambda!

回答by MSN

If your lambda is stateless, i.e., [](...){...}, C++11 allows it to degrade into a function pointer. In theory, a C++11 compliant compiler would be able to compile this:

如果您的 lambda 是无状态的,即,[](...){...}C++11 允许它降级为函数指针。理论上,一个 C++11 兼容的编译器将能够编译这个:

auto ignore = []() { return 10; };  //1 note misssing & in []!
std::vector<int (*)()> v;     //2
v.push_back([]() { return 100; });  //3

回答by antediluvian

You could use a lambda generating function (updated with fix suggested by Nawaz):

您可以使用 lambda 生成函数(使用 Nawaz 建议的修复更新):

#include <vector>
#include <iostream>

int main() {
    auto lambda_gen = [] (int i) {return [i](int x){ return i*x;};} ;

    using my_lambda = decltype(lambda_gen(1));

    std::vector<my_lambda> vec;

    for(int i = 0; i < 10; i++) vec.push_back(lambda_gen(i));

    int i = 0;

    for (auto& lambda : vec){
        std::cout << lambda(i) << std::endl;
        i++;
    }
}

But I think you basically made your own class at this point. Otherwise if the lambdas have completely different caputres/args etc. you probably have to use a tuple.

但我认为此时您基本上创建了自己的课程。否则,如果 lambdas 具有完全不同的 caputres/args 等,您可能必须使用元组。

回答by Paul Fultz II

Each lambda is a different type. You must use std::tupleinstead of std::vector.

每个 lambda 都是不同的类型。您必须使用std::tuple代替std::vector