Sdílet prostřednictvím


Příklady výrazů lambda

Tento článek ukazuje, jak můžete použít výrazy lambda v programech. Přehled výrazů lambda najdete v tématu Výrazy lambda. Další informace o struktuře výrazu lambda naleznete v tématu Syntaxe výrazu lambda.

Deklarace výrazů lambda

Příklad 1

Vzhledem k tomu, že je zadaný výraz lambda, můžete ho přiřadit proměnné auto nebo objektu function , jak je znázorněno zde:

// declaring_lambda_expressions1.cpp
// compile with: /EHsc /W4
#include <functional>
#include <iostream>

int main()
{
    using namespace std;

    // Assign the lambda expression that adds two numbers to an auto variable.
    auto f1 = [](int x, int y) { return x + y; };

    cout << f1(2, 3) << endl;

    // Assign the same lambda expression to a function object.
    function<int(int, int)> f2 = [](int x, int y) { return x + y; };

    cout << f2(3, 4) << endl;
}

Příklad vytvoří tento výstup:

5
7

Poznámky

Další informace naleznete v tématu auto, function třída a volání funkce.

Přestože výrazy lambda jsou nejčastěji deklarovány v těle funkce, můžete je deklarovat kdekoli, kde můžete inicializovat proměnnou.

Příklad 2

Kompilátor Jazyka Microsoft C++ vytvoří vazbu výrazu lambda na jeho zachycené proměnné, pokud je výraz deklarován místo při zavolání výrazu. Následující příklad ukazuje výraz lambda, který zachycuje místní proměnnou i podle hodnoty a místní proměnné j odkazem. Vzhledem k tomu, že výraz lambda zachycuje i hodnotu, opětovné přiřazení pozdějšího i výrazu v programu nemá vliv na výsledek výrazu. Vzhledem k tomu, že výraz lambda zachycuje j odkazem, má opětovné přiřazení j vliv na výsledek výrazu.

// declaring_lambda_expressions2.cpp
// compile with: /EHsc /W4
#include <functional>
#include <iostream>

int main()
{
   using namespace std;

   int i = 3;
   int j = 5;

   // The following lambda expression captures i by value and
   // j by reference.
   function<int (void)> f = [i, &j] { return i + j; };

   // Change the values of i and j.
   i = 22;
   j = 44;

   // Call f and print its result.
   cout << f() << endl;
}

Příklad vytvoří tento výstup:

47

[V tomto článku]

Volání výrazů lambda

Výraz lambda můžete volat ihned, jak je znázorněno v následujícím fragmentu kódu. Druhý fragment kódu ukazuje, jak předat lambda jako argument algoritmům standardní knihovny C++, jako find_ifje .

Příklad 1

Tento příklad deklaruje výraz lambda, který vrátí součet dvou celých čísel a volá výraz okamžitě s argumenty 5 a 4:

// calling_lambda_expressions1.cpp
// compile with: /EHsc
#include <iostream>

int main()
{
   using namespace std;
   int n = [] (int x, int y) { return x + y; }(5, 4);
   cout << n << endl;
}

Příklad vytvoří tento výstup:

9

Příklad 2

Tento příklad předá výraz lambda jako argument funkci find_if . Výraz lambda vrátí true , pokud je jeho parametr sudým číslem.

// calling_lambda_expressions2.cpp
// compile with: /EHsc /W4
#include <list>
#include <algorithm>
#include <iostream>

int main()
{
    using namespace std;

    // Create a list of integers with a few initial elements.
    list<int> numbers;
    numbers.push_back(13);
    numbers.push_back(17);
    numbers.push_back(42);
    numbers.push_back(46);
    numbers.push_back(99);

    // Use the find_if function and a lambda expression to find the
    // first even number in the list.
    const list<int>::const_iterator result =
        find_if(numbers.begin(), numbers.end(),[](int n) { return (n % 2) == 0; });

    // Print the result.
    if (result != numbers.end()) {
        cout << "The first even number in the list is " << *result << "." << endl;
    } else {
        cout << "The list contains no even numbers." << endl;
    }
}

Příklad vytvoří tento výstup:

The first even number in the list is 42.

Poznámky

Další informace o find_if funkci naleznete v tématu find_if. Další informace o funkcích standardní knihovny C++, které provádějí běžné algoritmy, naleznete v tématu <algorithm>.

[V tomto článku]

Vnoření výrazů lambda

Příklad

Výraz lambda můžete vnořit do jiného tak, jak je ukázáno v následujícím příkladu. Vnitřní výraz lambda vynásobí svůj argument 2 a vrátí výsledek. Vnější výraz lambda volá vnitřní výraz lambda s argumentem a k výsledku přičte 3.

// nesting_lambda_expressions.cpp
// compile with: /EHsc /W4
#include <iostream>

int main()
{
    using namespace std;

    // The following lambda expression contains a nested lambda
    // expression.
    int timestwoplusthree = [](int x) { return [](int y) { return y * 2; }(x) + 3; }(5);

    // Print the result.
    cout << timestwoplusthree << endl;
}

Příklad vytvoří tento výstup:

13

Poznámky

V tomto příkladu [](int y) { return y * 2; } je vnořený výraz lambda.

[V tomto článku]

Funkce lambda vyššího řádu

Příklad

Mnoho programovacích jazyků podporuje koncept funkce vyššího řádu. Funkce vyššího řádu je výraz lambda, který jako argument přebírá jiný výraz lambda nebo vrací výraz lambda. Třídu můžete použít function k povolení chování výrazu lambda jazyka C++ jako funkce vyššího pořadí. Následující příklad ukazuje výraz lambda, který vrací function objekt a výraz lambda, který přebírá function objekt jako svůj argument.

// higher_order_lambda_expression.cpp
// compile with: /EHsc /W4
#include <iostream>
#include <functional>

int main()
{
    using namespace std;

    // The following code declares a lambda expression that returns
    // another lambda expression that adds two numbers.
    // The returned lambda expression captures parameter x by value.
    auto addtwointegers = [](int x) -> function<int(int)> {
        return [=](int y) { return x + y; };
    };

    // The following code declares a lambda expression that takes another
    // lambda expression as its argument.
    // The lambda expression applies the argument z to the function f
    // and multiplies by 2.
    auto higherorder = [](const function<int(int)>& f, int z) {
        return f(z) * 2;
    };

    // Call the lambda expression that is bound to higherorder.
    auto answer = higherorder(addtwointegers(7), 8);

    // Print the result, which is (7+8)*2.
    cout << answer << endl;
}

Příklad vytvoří tento výstup:

30

[V tomto článku]

Použití výrazu lambda ve funkci

Příklad

Výrazy lambda můžete použít v těle funkce. Výraz lambda má přístup k libovolné funkci nebo datovému členu, ke kterému má nadřazená funkce přístup. Ukazatel můžete explicitně nebo implicitně zachytit this tak, aby poskytoval přístup k funkcím a datovým členům nadřazené třídy. Visual Studio 2017 verze 15.3 a novější (k dispozici s /std:c++17 a novější): Zachytávání this podle hodnoty ([*this]) při použití lambda v asynchronních nebo paralelních operacích, kde se kód může spustit po ukončení původního objektu mimo rozsah.

Ukazatel můžete použít this explicitně ve funkci, jak je znázorněno tady:

// capture "this" by reference
void ApplyScale(const vector<int>& v) const
{
   for_each(v.begin(), v.end(),
      [this](int n) { cout << n * _scale << endl; });
}

// capture "this" by value (Visual Studio 2017 version 15.3 and later)
void ApplyScale2(const vector<int>& v) const
{
   for_each(v.begin(), v.end(),
      [*this](int n) { cout << n * _scale << endl; });
}

Ukazatel můžete zachytit také this implicitně:

void ApplyScale(const vector<int>& v) const
{
   for_each(v.begin(), v.end(),
      [=](int n) { cout << n * _scale << endl; });
}

Následující příklad ukazuje Scale třídu, která zapouzdřuje hodnotu škálování.

// function_lambda_expression.cpp
// compile with: /EHsc /W4
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

class Scale
{
public:
    // The constructor.
    explicit Scale(int scale) : _scale(scale) {}

    // Prints the product of each element in a vector object
    // and the scale value to the console.
    void ApplyScale(const vector<int>& v) const
    {
        for_each(v.begin(), v.end(), [=](int n) { cout << n * _scale << endl; });
    }

private:
    int _scale;
};

int main()
{
    vector<int> values;
    values.push_back(1);
    values.push_back(2);
    values.push_back(3);
    values.push_back(4);

    // Create a Scale object that scales elements by 3 and apply
    // it to the vector object. doesn't modify the vector.
    Scale s(3);
    s.ApplyScale(values);
}

Příklad vytvoří tento výstup:

3
6
9
12

Poznámky

Funkce ApplyScale používá výraz lambda k vytištění součinu hodnoty měřítka a každého prvku v objektu vector . Výraz lambda implicitně zachycuje this , aby mohl přistupovat k členu _scale .

[V tomto článku]

Použití výrazů lambda se šablonami

Příklad

Protože výrazy lambda mají typ, můžete je použít s šablonami jazyka C++. Následující příklad ukazuje negate_all funkce a print_all funkce. Funkce negate_all použije unární operator- pro každý prvek v objektu vector . Funkce print_all vytiskne každý prvek v objektu vector do konzoly.

// template_lambda_expression.cpp
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// Negates each element in the vector object. Assumes signed data type.
template <typename T>
void negate_all(vector<T>& v)
{
    for_each(v.begin(), v.end(), [](T& n) { n = -n; });
}

// Prints to the console each element in the vector object.
template <typename T>
void print_all(const vector<T>& v)
{
    for_each(v.begin(), v.end(), [](const T& n) { cout << n << endl; });
}

int main()
{
    // Create a vector of signed integers with a few elements.
    vector<int> v;
    v.push_back(34);
    v.push_back(-43);
    v.push_back(56);

    print_all(v);
    negate_all(v);
    cout << "After negate_all():" << endl;
    print_all(v);
}

Příklad vytvoří tento výstup:

34
-43
56
After negate_all():
-34
43
-56

Poznámky

Další informace o šablonách jazyka C++ naleznete v tématu Šablony.

[V tomto článku]

Zpracování výjimek

Příklad

Tělo výrazu lambda je v souladu s pravidly pro strukturované zpracování výjimek (SEH) i zpracování výjimek jazyka C++. V těle výrazu lambda můžete zpracovat vyvolanou výjimku nebo pozdržet zpracování výjimek pro nadřazený obor. Následující příklad používá for_each funkci a výraz lambda k vyplnění vector objektu hodnotami jiného objektu. Používá try/catch blok pro zpracování neplatného přístupu k prvnímu vektoru.

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

int main()
{
    // Create a vector that contains 3 elements.
    vector<int> elements(3);

    // Create another vector that contains index values.
    vector<int> indices(3);
    indices[0] = 0;
    indices[-1] = 1; // This is not a valid subscript. It will trigger an exception.
    indices[2] = 2;

    // Use the values from the vector of index values to
    // fill the elements vector. This example uses a
    // try/catch block to handle invalid access to the
    // elements vector.
    try
    {
        for_each(indices.begin(), indices.end(), [&](int index) {
            elements.at(index) = index;
        });
    }
    catch (const out_of_range& e)
    {
        cerr << "Caught '" << e.what() << "'." << endl;
    };
}

Příklad vytvoří tento výstup:

Caught 'invalid vector<T> subscript'.

Poznámky

Další informace o zpracovánívýjimekch

[V tomto článku]

Použití výrazů lambda se spravovanými typy (C++/CLI)

Příklad

Klauzule capture výrazu lambda nemůže obsahovat proměnnou, která má spravovaný typ. Můžete však předat argument se spravovaným typem do seznamu parametrů výrazu lambda. Následující příklad obsahuje výraz lambda, který zachycuje místní nespravovanou proměnnou ch podle hodnoty a přebírá System.String objekt jako jeho parametr.

// managed_lambda_expression.cpp
// compile with: /clr
using namespace System;

int main()
{
    char ch = '!'; // a local unmanaged variable

    // The following lambda expression captures local variables
    // by value and takes a managed String object as its parameter.
    [=](String ^s) {
        Console::WriteLine(s + Convert::ToChar(ch));
    }("Hello");
}

Příklad vytvoří tento výstup:

Hello!

Poznámky

Výrazy lambda můžete použít také s knihovnou STL/CLR. Další informace naleznete v tématu STL/CLR Library Reference.

Důležité

Lambda nejsou podporovány v těchto spravovaných entitách CLR (Common Language Runtime): ref class, ref struct, value classa value struct.

[V tomto článku]

Viz také

Výrazy lambda
Syntaxe výrazů lambda
auto
function Třída
find_if
<algorithm>
Volání funkcí
Šablony
Zpracování výjimek
Referenční dokumentace knihoven STL/CLR