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

泛型lambdas的编译器推导类型

  •  9
  • qdii  · 技术社区  · 9 年前

    在里面 this article ,显示以下代码:

    std::vector<int> ivec = { 1, 2, 3, 4};
    std::vector<std::string> svec = { "red", "green", "blue" };
    auto adder = [](auto op1, auto op2){ return op1 + op2; };
    std::cout << "int result : "
              << std::accumulate(ivec.begin(),
                                 ivec.end(),
                                 0,
                                 adder)
              << "\n";
    std::cout << "string result : "
              << std::accumulate(svec.begin(),
                                 svec.end(),
                                 std::string(""),
                                 adder)
              << "\n";
    

    如果我理解正确的话,编译器将生成一个内部类,非常像下面这个:

    template<class T>
    class _lambda
    {
      public:
      T operator()(T lhs, T rhs) { return lhs + rhs; }
    };
    

    但我不明白的是,在这段代码中,加法器似乎同时有两种类型: _lambda<int> _lambda<string> 。这怎么可能?

    3 回复  |  直到 9 年前
        1
  •  8
  •   101010    9 年前

    根据标准5.1.2/p5λ表达式[expr.prim.Lambda]:

    对于泛型lambda,闭包类型有一个公共内联函数 调用其模板参数列表的操作员成员模板(14.5.2) 由一个发明的类型模板参数组成 lambdas参数声明子句中的auto,顺序为 外貌

    因此,实际生成的是:

    class _lambda {
    public:
        template<typename T1, typename T2>
        auto operator()(T1 lhs, T2 rhs) const { return lhs + rhs; }
    };
    
        2
  •  8
  •   bolov    9 年前

    不。它生成如下内容:

    class _lambda {
    public:
        template<class T1, class T2>
        auto operator()(T1 lhs, T2 rhs) const { return lhs + rhs; }
    };
    

    该类没有模板化。这个 operator()

        3
  •  1
  •   YSC    9 年前

    事实上,编译器将生成如下所示的类:

    class _lambda {
    public:
        template<class T, class U>
        auto operator()(T lhs, U rhs) const { return lhs + rhs; }
    };
    

    这两个参数不一定是同一类型的,唯一的条件是 operator+() 关于参数类型。

    看下面的演示 coliru .