通用lambda的编译器推导类型

时间:2015-12-31 11:08:14

标签: c++ lambda c++14 type-deduction

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 个答案:

答案 0 :(得分:8)

不。它生成这样的东西:

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

这门课没有模板化。 operator()是。

答案 1 :(得分:8)

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

  

对于通用lambda,闭包类型具有公共内联函数   调用操作员成员模板(14.5.2),其template-parameter-list   由每个出现的一个发明的类型模板参数组成   在lambda的parameter-declaration-clause中按顺序自动执行   外观

因此,实际生成的是:

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

答案 2 :(得分:1)

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

strncpy

这两个参数不一定是同一类型,唯一的条件是temp[i]->name[0] = '\0';与参数类型的存在。

查看coliru上的演示。