C++ 通用lambda在C++;14?

C++ 通用lambda在C++;14?,c++,lambda,auto,c++14,C++,Lambda,Auto,C++14,在C++14标准中,泛型lambda如何工作(auto关键字作为参数类型) 是基于C++模板的,对于每个不同的参数类型编译器,都用相同的主体生成一个新函数,但是替换类型(编译时多态),或者它更类似于java的泛型(类型擦除)?p> 代码示例: auto glambda = [](auto a) { return a; }; 通用lambda是在C++14中引入的 简单地说,lambda表达式定义的闭包类型将有一个模板调用运算符,而不是C++11的lambda的常规非模板调用运算符(当然,当au

在C++14标准中,泛型lambda如何工作(
auto
关键字作为参数类型)

是基于C++模板的,对于每个不同的参数类型编译器,都用相同的主体生成一个新函数,但是替换类型(编译时多态),或者它更类似于java的泛型(类型擦除)?p> 代码示例:

auto glambda = [](auto a) { return a; };

通用lambda是在C++14中引入的

简单地说,lambda表达式定义的闭包类型将有一个模板调用运算符,而不是
C++11
的lambda的常规非模板调用运算符(当然,当
auto
在参数列表中至少出现一次时)

所以你的例子是:

auto glambda = [] (auto a) { return a; };
将使
glambda
成为此类型的实例:

class /* unnamed */
{
public:
    template<typename T>
    T operator () (T a) const { return a; }
};
class/*未命名*/
{
公众:
模板
T运算符()(ta)常量{返回a;}
};
C++14标准草案n3690第5.1.2/5段规定了如何定义给定lambda表达式的闭包类型的调用运算符:

非泛型lambda表达式的闭包类型具有公共内联函数调用运算符(13.5.4) 其参数和返回类型由lambda表达式的参数声明子句描述 和尾随返回类型对于泛型lambda,闭包类型具有公共内联函数调用 操作员成员模板(14.5.2),其模板参数列表由一个虚构类型模板参数组成 对于lambda的参数声明子句中出现的每一个auto,按照出现的顺序。 如果相应的参数声明声明 功能参数包(8.3.5)。函数调用的返回类型和函数参数 运算符模板派生自lambda表达式的尾部返回类型和参数declaration子句 通过将参数声明子句的decl说明符中出现的每个auto替换为 相应模板参数的名称

最后:

它类似于模板,每个不同的参数类型编译器都会生成具有相同主体但类型已更改的函数,还是更类似于Java的泛型


如上所述,泛型lambda只是具有模板化调用运算符的唯一未命名函子的语法糖。这应该可以回答您的问题:)不幸的是,它们不是C++11()的一部分:

使用g++4.7:

prog.cpp:1:24: error: parameter declared ‘auto’
...

但是,它在C++14中的实现方式如下所示:

这将在很大程度上产生通常创建的匿名函子类,但由于缺少类型,编译器将发出一个模板成员-
操作符()

struct匿名
{
模板
自动运算符()
{返回x+y;}
};
或者按照最新的提议

autol=[](const auto&x,auto&y){return x+y;};
--->
struct/*匿名*/
{
模板
自动运算符()(常量T&x,U&y)常量//N3386返回类型扣除
{返回x+y;}
}L;

因此,是的,对于参数的每一个排列,都会出现一个新的实例化,但是,该函子的成员仍然是共享的(即捕获的参数)。

这是一个建议的C++14特性(在C++11中不是),类似于(甚至等效于)模板。例如,提供了以下示例:

例如,此通用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;
struct/*匿名*/
{
模板
自动运算符()(常量T&x,U&y)常量//N3386返回类型扣除
{返回x+y;}
}L;

但是,它们也允许使用模板方法创建本地定义的类。这是新的。@Yakk:对函数本地模板的限制不是已经随C++11一起取消了吗?@phresnel:没有,这个限制还没有取消lifted@AndyProwl当前位置我意识到我的错误。事实上,取消的是使用本地类型作为模板参数(如
intmain(){struct X{};std::vector X;}
)@phresnel:Right,它已经改为C++14,最初使用C++11时有疑问,允许删除类型说明符的建议是完全荒谬的。他们同意了。你需要提供
-std=c++1y
。我没有意识到ideone还没有gcc-4.9和c++14。问题:这个
auto
与经典的auto有相同的演绎规则吗?如果我们提到模板化的类比,它将意味着auto不是auto,它与模板类型推断的规则相同。然后问题是:模板演绎是否等同于
auto
?@v.oddou:“经典汽车”是好的。对我来说,“classic auto”意味着“Stack Variable”(堆栈变量),曾经用于与
static
register
:)形成对比。无论如何,是的,使用
auto
意味着在引擎盖下生成正常模板。事实上,lambda将在编译器内部被functor类替换,而
auto
参数意味着
template。。。(T…
将被发出。
struct anonymous
{
    template <typename T, typename U>
    auto operator()(T const& x, U& y) const -> decltype(x+y)
    { return x + y; }
};
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;
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;