Delen via


Syntaxis van lambda-expressie

In dit artikel worden de syntaxis en structurele elementen van lambda-expressies gedemonstreert. Zie Lambda-expressies voor een beschrijving van lambda-expressies.

Functieobjecten versus Lambdas

Wanneer u code schrijft, gebruikt u waarschijnlijk functiepointers en functieobjecten om problemen op te lossen en berekeningen uit te voeren, met name wanneer u C++ Standard Library-algoritmen gebruikt. Functiepointers en functieobjecten hebben allemaal voor- en nadelen, bijvoorbeeld functiepointers hebben minimale syntactische overhead, maar behouden de status niet binnen een bereik en functieobjecten kunnen status behouden, maar vereisen de syntactische overhead van een klassedefinitie.

Een lambda combineert de voordelen van functiepointers en functieobjecten en voorkomt hun nadelen. Net als een functieobject is een lambda flexibel en kan de status behouden, maar in tegenstelling tot een functieobject is de compacte syntaxis geen expliciete klassedefinitie vereist. Met behulp van lambdas kunt u code schrijven die minder omslachtig en minder gevoelig is voor fouten dan de code voor een equivalent functieobject.

In de volgende voorbeelden wordt het gebruik van een lambda vergeleken met het gebruik van een functieobject. In het eerste voorbeeld wordt een lambda gebruikt om af te drukken naar de console, ongeacht of elk element in een vector object even of oneven is. In het tweede voorbeeld wordt een functieobject gebruikt om dezelfde taak uit te voeren.

Voorbeeld 1: Een Lambda gebruiken

In dit voorbeeld wordt een lambda doorgegeven aan de functie for_each . De lambda drukt een resultaat af dat aangeeft of elk element in een vector object even of oneven is.

Code

// even_lambda.cpp
// compile with: cl /EHsc /nologo /W4 /MTd
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
   // Create a vector object that contains 9 elements.
   vector<int> v;
   for (int i = 1; i < 10; ++i) {
      v.push_back(i);
   }

   // Count the number of even numbers in the vector by
   // using the for_each function and a lambda.
   int evenCount = 0;
   for_each(v.begin(), v.end(), [&evenCount] (int n) {
      cout << n;
      if (n % 2 == 0) {
         cout << " is even " << endl;
         ++evenCount;
      } else {
         cout << " is odd " << endl;
      }
   });

   // Print the count of even numbers to the console.
   cout << "There are " << evenCount
        << " even numbers in the vector." << endl;
}
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
There are 4 even numbers in the vector.

Opmerkingen

In het voorbeeld is het derde argument voor de functie for_each een lambda. In [&evenCount] het gedeelte wordt de capture-component van de expressie opgegeven, (int n) wordt de lijst met parameters opgegeven en het resterende deel geeft de hoofdtekst van de expressie op.

Voorbeeld 2: Een functieobject gebruiken

Soms zou een lambda te onhandig zijn om veel verder uit te breiden dan in het vorige voorbeeld. In het volgende voorbeeld wordt een functieobject gebruikt in plaats van een lambda, samen met de functie for_each , om dezelfde resultaten te produceren als voorbeeld 1. In beide voorbeelden wordt het aantal even getallen in een vector object opgeslagen. De klasse slaat de m_evenCount variabele op als lidvariabele om de status van de bewerking FunctorClass te behouden. Als u de bewerking wilt uitvoeren, FunctorClass implementeert u de operator voor functie-aanroep, operator(). De Microsoft C++-compiler genereert code die vergelijkbaar is met de grootte en prestaties van de lambda-code in voorbeeld 1. Voor een eenvoudig probleem, zoals in dit artikel, is het eenvoudigere lambda-ontwerp waarschijnlijk beter dan het ontwerp van functieobjecten. Als u echter denkt dat de functionaliteit in de toekomst een aanzienlijke uitbreiding kan vereisen, gebruikt u een functieobjectontwerp, zodat codeonderhoud eenvoudiger is.

Zie Functieoproep voor meer informatie over de operator(). Zie for_each voor meer informatie over de functie for_each.

Code

// even_functor.cpp
// compile with: /EHsc
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

class FunctorClass
{
public:
    // The required constructor for this example.
    explicit FunctorClass(int& evenCount)
        : m_evenCount(evenCount) { }

    // The function-call operator prints whether the number is
    // even or odd. If the number is even, this method updates
    // the counter.
    void operator()(int n) const {
        cout << n;

        if (n % 2 == 0) {
            cout << " is even " << endl;
            ++m_evenCount;
        } else {
            cout << " is odd " << endl;
        }
    }

private:
    // Default assignment operator to silence warning C4512.
    FunctorClass& operator=(const FunctorClass&);

    int& m_evenCount; // the number of even variables in the vector.
};

int main()
{
    // Create a vector object that contains 9 elements.
    vector<int> v;
    for (int i = 1; i < 10; ++i) {
        v.push_back(i);
    }

    // Count the number of even numbers in the vector by
    // using the for_each function and a function object.
    int evenCount = 0;
    for_each(v.begin(), v.end(), FunctorClass(evenCount));

    // Print the count of even numbers to the console.
    cout << "There are " << evenCount
        << " even numbers in the vector." << endl;
}
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
There are 4 even numbers in the vector.

Zie ook

Lambda-expressies
Voorbeelden van Lambda-expressies
genereren
generate_n
for_each
Uitzonderingsspecificaties (gooien)
Compilerwaarschuwing (niveau 1) C4297
Microsoft-Specific modificeerders