如何声明函数向量(lambdas)

时间:2016-11-22 07:43:30

标签: c++ c++11 c++14

我已经了解了如何声明函数向量(参见calling a function from a vector)。

但是答案用户指针。如何使用现代C ++中的新语法创建函数/ lambda的向量?

使用新语法的函数示例通常使用auto:

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

f的实际类型是什么?所以我可以声明这种类型的矢量吗?

非常感谢你的帮助

3 个答案:

答案 0 :(得分:13)

std::vector<std::function<void(void)>> vec; vec.push_back([]()->void{}); 与相应的类型一起使用:

std::function<void(std::string)>

在您的情况下,它将是product share_per return_per min_share_per prod1 0.5 0.1 0.2 prod2 0.2 0.4 0.1 prod3 0.2 0.05 0.0 prod4 0.1 0.04 0.0 prod5 0.0 0.3 0.0

根据标准([expr.prim.lambda] / 3),lambda的确切类型毫无意义:

  

lambda-expression的类型(也是闭包对象的类型)是一个唯一的,未命名的非联合类类型

答案 1 :(得分:7)

  

f的实际类型是什么?所以我可以声明这种类型的矢量吗?

f的类型只能使用auto推断。您可以使用

声明此类型的vector
std::vector<decltype(f)> v;

但是,它不是很有用。看起来非常相似的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::vector std::function个。您可以将lambda函数添加到std::vector。鉴于fg的上述定义,您可以使用:

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

答案 2 :(得分:0)

如上所述,您声明的每个lambda都具有唯一的特定于上下文的类型,即使它具有看似相同的签名。这就是为什么lambdas的向量只有理论价值 - 你最多可以推动一个lambda ...你有两个选择 - 你可以从其他答案中提出建议的方法并将lambda存储到类型擦除{{在将它们放入向量或将lambda放入一个“容器”之前,它将收集除lambda对象本身之外的每个元素的类型 - std::function

std::tuple

并在编译时获取适当的lambda:

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

[live demo]