使用gcc 4.9 -std = c ++ 14,我尝试制作一个lambdas向量:
vector<function<void ()>> v = {[]{cout << "foo";}, []{cout << "bar";}};
for (auto&& a: v) a();
Run Code Online (Sandbox Code Playgroud)
它运作得很好.然后我尝试将lambdas的初始化列表直接传递给基于范围:
for (auto&& a: {[]{cout << "foo";}, []{cout << "bar";}}) a();
Run Code Online (Sandbox Code Playgroud)
我得到了:
error: unable to deduce 'std::initializer_list<auto>&&' from '{<lambda closure object>main()::<lambda()>{}, <lambda closure object>main()::<lambda()>{}}'
Run Code Online (Sandbox Code Playgroud)
从错误消息的外观来看,我猜测它可能是因为" lambda闭包对象 "是内置语言术语,而不是std :: function的直接等价物(因此没有实际类型).
这个的深层原因是什么?此外,这可能是与实现相关的,还是由规范决定的行为?
每个lambda都有自己独特的类型.所以你可能不会从不同类型的lambdas构建std :: initializer_list.
根据C++标准(5.1.2 Lambda表达式)
3 lambda-expression 的类型(也是闭包对象的类型)是一个唯一的,未命名的nonunion类类型 - 称为闭包类型 - 其属性如下所述.
也
6没有lambda-capture的非泛型lambda表达式的闭包类型有一个公共的非虚拟非显式const转换函数,指向函数,C++语言链接(7.5)具有与闭包类型函数相同的参数和返回类型呼叫运营商.
每个lamdba都有自己的类型,因此编译器无法推断出类型initializer_list
.
你必须告诉你想要哪种类型:
对于每个lambda:
由于你的lambda不捕获变量,你可以将它们衰减到指向函数的指针,+
如下所示:
for (auto&& a: {+[]{std::cout << "foo";}, +[]{std::cout << "bar";}}) a();
Run Code Online (Sandbox Code Playgroud)使用function<void()>
:
for (auto&& a: {std::function<void()>([]{std::cout << "foo";}),
std::function<void()>([]{std::cout << "bar";})}) a();
Run Code Online (Sandbox Code Playgroud)对于initializer_list:
for (auto&& a: std::initializer_list<std::function<void()>>{
[]{std::cout << "foo";},
[]{std::cout << "bar";}}) a();
Run Code Online (Sandbox Code Playgroud)