Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler-deduced type for generic lambdas

In this article, the following code is presented:

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";

If I understand correctly, the compiler will generate an internal class much like this one:

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

But what I don't understand is, in this section of the code, adder seems to have two types at the same time: _lambda<int> and _lambda<string>. How is this possible?

like image 612
qdii Avatar asked Dec 31 '15 11:12

qdii


1 Answers

According to the standard 5.1.2/p5 Lambda expressions [expr.prim.lambda]:

For a generic lambda, the closure type has a public inline function call operator member template (14.5.2) whose template-parameter-list consists of one invented type template-parameter for each occurrence of auto in the lambda’s parameter-declaration-clause, in order of appearance.

Consequently, what is actually generated is:

class _lambda {
public:
    template<typename T1, typename T2>
    auto operator()(T1 lhs, T2 rhs) const { return lhs + rhs; }
};
like image 182
101010 Avatar answered Oct 17 '22 14:10

101010