genericslambda如何在C ++ 14中工作?
genericslambda在C ++ 14标准中如何工作( auto
关键字作为参数types)?
它是基于C ++模板,其中每个不同的参数types编译器生成一个具有相同的主体,但replacetypes(编译时多态性)的新function,或者是更类似于Java的generics(types擦除)?
代码示例:
auto glambda = [](auto a) { return a; };
genericslambdas是在C++14
中引入的。
简单地说,由lambdaexpression式定义的闭包types将具有一个模板化的调用操作符,而不是C++11
的lambdaexpression式的常规非模板调用操作符(当然,当auto
在参数列表中至less出现一次时)。
所以你的例子:
auto glambda = [] (auto a) { return a; };
将glambda
作为这种types的一个实例:
class /* unnamed */ { public: template<typename T> T operator () (T a) const { return a; } };
C ++ 14标准草案的第5.1.2 / 5节规定了给定lambdaexpression式的闭包types的调用操作符是如何定义的:
非genericslambdaexpression式的闭包types有一个公共的内联函数调用操作符(13.5.4),其参数和返回types分别由lambdaexpression式的parameter-declaration-clause和trailing-return-type来描述。 对于一个通用的lambda,闭包types有一个公共的内联函数调用操作员成员模板(14.5.2),其模板参数列表由一个发明的types模板参数组成,在lambda的参数声明子句中每次出现auto,按照外观顺序 。 如果相应的参数声明声明了一个函数参数包(8.3.5),那么本发明的types模板参数是一个参数包。 函数调用操作符模板的返回types和函数参数是通过将lambdaexpression式的trailing-return-type和parameter-declarationclause从参数声明子句的decl-specifier中的每个出现的autoreplace成相应发明的模板参数。
最后:
它是类似的模板,其中每个不同的参数types编译器生成具有相同的主体,但更改types的function,或者是更类似于Java的generics?
正如上面的段落所解释的那样,genericslambdas只是语法上的糖,用于带有模板调用操作符的独特函数。 这应该回答你的问题:)
不幸的是 ,它们不是C ++ 11的一部分( http://ideone.com/NsqYuq ):
auto glambda = [](auto a) { return a; }; int main() {}
用g ++ 4.7:
prog.cpp:1:24: error: parameter declared 'auto' ...
然而 ,按照波特兰对通用lambdas的build议,它可能在C ++ 14中实现:
[](const& x, & y){ return x + y; }
这将产生一个通常的匿名函数类的创build,但是由于缺lesstypes,编译器会发出一个模板化的成员operator()
:
struct anonymous { template <typename T, typename U> auto operator()(T const& x, U& y) const -> decltype(x+y) { return x + y; } };
或按照较新的关于通用(多态)Lambdaexpression式的提案
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;
所以是的,对于参数的每一个排列,都会出现一个新的实例,但是这个函数的成员仍然会被共享(即被捕获的参数)。
这是一个build议的C ++ 14function(不在C ++ 11中)与模板类似(甚至相当)。 例如, N3559提供了这个例子:
例如,这个通用的lambdaexpression式包含语句:
auto L = [](const auto& x, auto& y){ return x + y; };
可能会导致创build一个闭包types,并且对象的行为与下面的结构类似:
struct /* anonymous */ { template <typename T, typename U> auto operator()(const T& x, U& y) const // N3386 Return type deduction { return x + y; } } L;