2015-12-31 7 views
9

In this article, wird der folgende Code dargestellt:Compiler-abgeleiteten Typ für allgemeine lambdas

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

Wenn ich richtig verstehe, wird der Compiler eine interne Klasse wie diese viel generieren:

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

Aber was ich nicht verstehe, ist, dass der Addierer in diesem Abschnitt des Codes zwei Typen gleichzeitig zu haben scheint: _lambda<int> und _lambda<string>. Wie ist das möglich?

Antwort

8

Nach dem Standard 5.1.2/p5 Lambda-Ausdrücke [expr.prim.lambda]:

Für eine generische Lambda, der Verschluss-Typ hat eine öffentliche Inline-Funktion Call Operator Mitglied Vorlage (14.5. 2) dessen Template-Parameter-Liste besteht aus einem Template-Parameter vom Typ erfunden für jedes Auftreten von Auto in der Lambda-Parameter-Deklaration-Klausel, in der Reihenfolge Aussehen.

Folglich, was tatsächlich erzeugt wird:

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

Ebenso, wenn Argumente wie "Auto && lhs" sind. dann erzeugt es 'T && lhs' .. und so weiter. – Nawaz

8

Nein. Es erzeugt etwas in der Art:

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

Die Klasse ist nicht templated. Die operator() ist.

+0

ah ja das macht Sinn! Danke – qdii

+0

Ebenso, wenn Argumente wie "Auto && lhs" sind. dann erzeugt es 'T && lhs' .. und so weiter. – Nawaz

+1

@Nawaz in seinem Beispiel sind sie nicht – bolov

1

Als der Tat wird der Compiler eine Klasse erzeugen wie folgt aussehen:

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

Die beiden Argumente sind nicht unbedingt vom gleichen Typ ist die einzige Bedingung die Existenz eines operator+() mit den entsprechenden Argumenttypen.

Schauen Sie sich die Demo auf coliru an.

+0

Ich bin zu langsam :( – YSC

+0

Ebenso, wenn Argumente wie "auto && lhs" sind, dann erzeugt es 'T && lhs' .. und so weiter. – Nawaz