代码之家  ›  专栏  ›  技术社区  ›  thb

lambda是正确的对象吗?[副本]

  •  0
  • thb  · 技术社区  · 5 年前

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

    它是基于C++模板吗?在每个模板中,每个不同的参数类型编译器都会生成一个新函数,这个函数具有相同的主体,但替换的类型(编译时多态性)或更类似于Java的泛型(类型擦除)?

    代码示例:

    auto glambda = [](auto a) { return a; };
    
    0 回复  |  直到 10 年前
        1
  •  126
  •   WhiZTiM    8 年前

    通用lambdas在 C++14 是的。

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

    你的例子是:

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

    将使 glambda 此类实例:

    class /* unnamed */
    {
    public:
        template<typename T>
        T operator () (T a) const { return a; }
    };
    

    C++ 14标准草案的第1节详细说明了给定lambda表达式的闭包类型的调用操作符是如何定义的:

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

    最后:

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

    正如上面的段落所解释的,泛型lambda只是带有模板调用运算符的唯一的、未命名的函子的语法糖。这应该能回答你的问题:)

        2
  •  25
  •   Sebastian Mach    11 年前

    不幸的是 它们不是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’
    ...
    

    然而 它可以按照C++ 14的方式实现 Portland proposal for generic lambdas 以下内容:

    [](const& x, & y){ return x + y; }
    

    这将在很大程度上导致通常创建匿名函子类,但是由于缺少类型,编译器将发出一个模板成员- operator() 以下内容:

    struct anonymous
    {
        template <typename T, typename U>
        auto operator()(T const& x, U& y) const -> decltype(x+y)
        { return x + y; }
    };
    

    或者按照新的提议 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;
    

    所以是的,对于每一个参数的排列,都会产生一个新的实例化,然而,函子的成员仍然是共享的(即捕获的参数)。

        3
  •  15
  •   Cassio Neri    11 年前

    这是一个类似于(或相当于)模板的C++ 14特性(不在C++ 11)。例如, N3559 提供以下示例:

    例如,此包含语句的泛型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;