泛型 lambda 如何在 C++14 中工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17233547/
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
How does generic lambda work in C++14?
提问by sasha.sochka
How does generic lambda work (auto
keyword as an argument type) in C++14 standard?
泛型 lambdaauto
在 C++14 标准中如何工作(关键字作为参数类型)?
Is it based on C++ templates where for each different argument type compiler generates a new function with the same body but replaced types (compile-time polymorphism) or is it more similar to Java's generics (type erasure)?
它是基于 C++ 模板,其中对于每个不同的参数类型编译器生成一个具有相同主体但替换类型(编译时多态)的新函数,还是更类似于 Java 的泛型(类型擦除)?
Code example:
代码示例:
auto glambda = [](auto a) { return a; };
回答by Andy Prowl
Generic lambdas were introduced in C++14
.
中引入了通用 lambda 表达式C++14
。
Simply, the closure type defined by the lambda expression will have a templatedcall operator rather than the regular, non-template call operator of C++11
's lambdas (of course, when auto
appears at least once in the parameter list).
简单地说,由 lambda 表达式定义的闭包类型将具有模板化调用运算符,而不是的 lambda的常规非模板调用运算符C++11
(当然,当auto
在参数列表中至少出现一次时)。
So your example:
所以你的例子:
auto glambda = [] (auto a) { return a; };
Will make glambda
an instance of this type:
将创建glambda
此类型的实例:
class /* unnamed */
{
public:
template<typename T>
T operator () (T a) const { return a; }
};
Paragraph 5.1.2/5 of the C++14 Standard Draft n3690 specifies how the call operator of the closure type of a given lambda expression is defined:
C++14 标准草案 n3690 的第 5.1.2/5 段指定了如何定义给定 lambda 表达式的闭包类型的调用运算符:
The closure type for a non-generic lambda-expression has a public inline function call operator (13.5.4) whose parameters and return type are described by the lambda-expression's parameter-declaration-clause and trailing-return-type respectively. For a generic lambda, the closure type has a public inline function call operator member template (14.5.2) whose template-parameter-list consists of one invented type template-parameter for each occurrence of auto in the lambda's parameter-declaration-clause, in order of appearance. The invented type template-parameter is a parameter pack if the corresponding parameter-declaration declares a function parameter pack (8.3.5). The return type and function parameters of the function call operator template are derived from the lambda-expression's trailing-return-type and parameter-declarationclause by replacing each occurrence of auto in the decl-specifiers of the parameter-declaration-clause with the name of the corresponding invented template-parameter.
非泛型 lambda 表达式的闭包类型具有公共内联函数调用运算符 (13.5.4),其参数和返回类型分别由 lambda 表达式的参数声明子句和尾随返回类型描述。对于泛型 lambda,闭包类型有一个公共内联函数调用运算符成员模板 (14.5.2),其模板参数列表由一个发明的类型模板参数组成,用于在 lambda 的参数声明子句中每次出现 auto,按出场顺序. 如果相应的参数声明声明函数参数包(8.3.5),则发明的类型模板参数是参数包。函数调用运算符模板的返回类型和函数参数派生自 lambda 表达式的尾随返回类型和参数声明子句,方法是将参数声明子句的声明说明符中每次出现的 auto 替换为相应的发明模板参数。
Finally:
最后:
Is it similar to templates where for each different argument type compiler generates functions with the same body but changed types or is it more similar to Java's generics?
它是否类似于模板,其中为每个不同的参数类型编译器生成具有相同主体但类型改变的函数,还是更类似于 Java 的泛型?
As the above paragraph explains, generic lambdas are just syntactic sugar for unique, unnamed functors with a templated call operator. That should answer your question :)
正如上面的段落所解释的那样,泛型 lambda 只是具有模板化调用运算符的独特的、未命名的函子的语法糖。那应该回答你的问题:)
回答by Sebastian Mach
Unfortunately, they are not part of C++11 (http://ideone.com/NsqYuq):
不幸的是,它们不是 C++11 ( http://ideone.com/NsqYuq) 的一部分:
auto glambda = [](auto a) { return a; };
int main() {}
With g++ 4.7:
使用 g++ 4.7:
prog.cpp:1:24: error: parameter declared ‘auto'
...
However, the way it might be implemented in C++14 as per the Portland proposal for generic lambdas:
但是,根据Portland 对通用 lambda 的提议,它可能在 C++14 中实现的方式:
[](const& x, & y){ return x + y; }
This would yield for the biggest part the usual creation of an anonymous functor class, but with the lack of types the compiler would emit a templated member-operator()
:
这将在很大程度上产生匿名函子类的通常创建,但是由于缺少类型,编译器将发出模板化成员- operator()
:
struct anonymous
{
template <typename T, typename U>
auto operator()(T const& x, U& y) const -> decltype(x+y)
{ return x + y; }
};
Or as per the newer proposal Proposal for Generic (Polymorphic) Lambda Expressions
或者根据较新的提案Proposal for Generic (Polymorphic) Lambda Expressions
auto L = [](const auto& x, auto& y){ return x + y; };
--->
struct /* anonymous */
{
template <typename T, typename U>
auto operator()(const T& x, U& y) const // N3386 Return type deduction
{ return x + y; }
} L;
So yes, for every permutation of parameters, a new instantiation would arise, however, the members of that functor would still be shared (i.e. the captured arguments).
所以是的,对于参数的每次排列,都会出现一个新的实例化,但是,该函子的成员仍将被共享(即捕获的参数)。
回答by Cassio Neri
It's a proposed C++14 feature (not in C++11) similar (or even equivalent) to templates. For instance, N3559provides this example:
这是一个提议的 C++14 特性(不在 C++11 中),类似于(甚至等同于)模板。例如,N3559提供了以下示例:
For example, this generic lambda-expression containing statement:
auto L = [](const auto& x, auto& y){ return x + y; };
might result in the creation of a closure type, and object that behaves similar to the struct below:
struct /* anonymous */ { template <typename T, typename U> auto operator()(const T& x, U& y) const // N3386 Return type deduction { return x + y; } } L;
例如,这个包含语句的通用 lambda 表达式:
auto L = [](const auto& x, auto& y){ return x + y; };
可能会导致创建一个闭包类型,以及行为类似于以下结构的对象:
struct /* anonymous */ { template <typename T, typename U> auto operator()(const T& x, U& y) const // N3386 Return type deduction { return x + y; } } L;