Contoh Ekspresi Lambda

Artikel ini memperlihatkan cara menggunakan ekspresi lambda dalam program Anda. Untuk gambaran umum ekspresi lambda, lihat Ekspresi Lambda. Untuk informasi selengkapnya tentang struktur ekspresi lambda, lihat Sintaks Ekspresi Lambda.

Mendeklarasikan Ekspresi Lambda

Contoh 1

Karena ekspresi lambda ditik, Anda dapat menetapkannya ke auto variabel atau ke objek, seperti yang function ditunjukkan di sini:

// 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;
}

Contoh menghasilkan output ini:

5
7

Keterangan

Untuk informasi selengkapnya, lihat auto, function Kelas, dan Panggilan Fungsi.

Meskipun ekspresi lambda paling sering dideklarasikan dalam isi fungsi, Anda dapat mendeklarasikannya di mana saja bahwa Anda dapat menginisialisasi variabel.

Contoh 2

Pengkompilasi Microsoft C++ mengikat ekspresi lambda ke variabel yang ditangkap ketika ekspresi dideklarasikan alih-alih ketika ekspresi dipanggil. Contoh berikut menunjukkan ekspresi lambda yang mengambil variabel i lokal berdasarkan nilai dan variabel j lokal berdasarkan referensi. Karena ekspresi lambda diambil i berdasarkan nilai, penetapan i ulang nanti dalam program tidak memengaruhi hasil ekspresi. Namun, karena ekspresi lambda diambil j berdasarkan referensi, penetapan j ulang memang memengaruhi hasil ekspresi.

// 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;
}

Contoh menghasilkan output ini:

47

[Dalam artikel ini]

Memanggil Ekspresi Lambda

Anda dapat segera memanggil ekspresi lambda, seperti yang ditunjukkan pada cuplikan kode berikutnya. Cuplikan kedua menunjukkan cara meneruskan lambda sebagai argumen ke algoritma Pustaka Standar C++ seperti find_if.

Contoh 1

Contoh ini mendeklarasikan ekspresi lambda yang mengembalikan jumlah dua bilangan bulat dan memanggil ekspresi segera dengan argumen 5 dan 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;
}

Contoh menghasilkan output ini:

9

Contoh 2

Contoh ini meneruskan ekspresi lambda sebagai argumen ke find_if fungsi . Ekspresi lambda mengembalikan true jika parameternya adalah angka genap.

// 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;
    }
}

Contoh menghasilkan output ini:

The first even number in the list is 42.

Keterangan

Untuk informasi selengkapnya tentang fungsi ini find_if , lihat find_if. Untuk informasi selengkapnya tentang fungsi Pustaka Standar C++ yang melakukan algoritma umum, lihat <algorithm>.

[Dalam artikel ini]

Ekspresi Lambda Berlapis

Contoh

Anda dapat menumpuk ekspresi lambda di dalam ekspresi lain, seperti yang ditunjukkan dalam contoh ini. Ekspresi lambda dalam mengalikan argumennya dengan 2 dan mengembalikan hasilnya. Ekspresi lambda luar memanggil ekspresi lambda bagian dalam dengan argumennya dan menambahkan 3 ke hasilnya.

// 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;
}

Contoh menghasilkan output ini:

13

Keterangan

Dalam contoh ini, [](int y) { return y * 2; } adalah ekspresi lambda berlapis.

[Dalam artikel ini]

Fungsi Lambda Berurutan Lebih Tinggi

Contoh

Banyak bahasa pemrograman mendukung konsep fungsi dengan urutan yang lebih tinggi. Fungsi urutan yang lebih tinggi adalah ekspresi lambda yang mengambil ekspresi lambda lain sebagai argumennya atau mengembalikan ekspresi lambda. Anda dapat menggunakan function kelas untuk mengaktifkan ekspresi lambda C++ agar bertingkah seperti fungsi urutan yang lebih tinggi. Contoh berikut menunjukkan ekspresi lambda yang mengembalikan function objek dan ekspresi lambda yang mengambil function objek sebagai argumennya.

// 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;
}

Contoh menghasilkan output ini:

30

[Dalam artikel ini]

Menggunakan Ekspresi Lambda dalam Fungsi

Contoh

Anda dapat menggunakan ekspresi lambda dalam isi fungsi. Ekspresi lambda dapat mengakses fungsi atau anggota data apa pun yang dapat diakses oleh fungsi penutup. Anda dapat secara eksplisit atau implisit menangkap this penunjuk untuk menyediakan akses ke fungsi dan anggota data dari kelas penutup. Visual Studio 2017 versi 15.3 dan yang lebih baru (Tersedia dengan dan yang lebih baru): Ambil this berdasarkan /std:c++17 nilai ([*this]) ketika lambda akan digunakan dalam operasi asinkron atau paralel di mana kode mungkin dijalankan setelah objek asli keluar dari cakupan.

Anda dapat menggunakan penunjuk this secara eksplisit dalam fungsi, seperti yang ditunjukkan di sini:

// 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; });
}

Anda juga dapat menangkap pointer this secara implisit:

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

Contoh berikut menunjukkan Scale kelas , yang merangkum nilai skala.

// 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);
}

Contoh menghasilkan output ini:

3
6
9
12

Keterangan

Fungsi ini ApplyScale menggunakan ekspresi lambda untuk mencetak produk dari nilai skala dan setiap elemen dalam vector objek. Ekspresi lambda secara implisit this menangkap sehingga dapat mengakses _scale anggota.

[Dalam artikel ini]

Menggunakan Ekspresi Lambda dengan Templat

Contoh

Karena ekspresi lambda ditik, Anda dapat menggunakannya dengan templat C++. Contoh berikut menunjukkan negate_all fungsi dan print_all . Fungsi menerapkan negate_all unary operator- ke setiap elemen dalam vector objek. Fungsi mencetak print_all setiap elemen dalam vector objek ke konsol.

// 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);
}

Contoh menghasilkan output ini:

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

Keterangan

Untuk informasi selengkapnya tentang templat C++, lihat Templat.

[Dalam artikel ini]

Menangani Pengecualian

Contoh

Isi ekspresi lambda mengikuti aturan untuk penanganan pengecualian terstruktur (SEH) dan penanganan pengecualian C++. Anda dapat menangani pengecualian yang dinaikkan dalam isi ekspresi lambda atau menunda penanganan pengecualian ke cakupan penutup. Contoh berikut menggunakan for_each fungsi dan ekspresi lambda untuk mengisi vector objek dengan nilai yang lain. Ini menggunakan try/catch blok untuk menangani akses yang tidak valid ke vektor pertama.

// 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;
    };
}

Contoh menghasilkan output ini:

Caught 'invalid vector<T> subscript'.

Keterangan

Untuk informasi selengkapnya tentang penanganan pengecualian, lihat Penanganan Pengecualian.

[Dalam artikel ini]

Menggunakan Ekspresi Lambda dengan Jenis Terkelola (C++/CLI)

Contoh

Klausa pengambilan ekspresi lambda tidak boleh berisi variabel yang memiliki jenis terkelola. Namun, Anda dapat meneruskan argumen yang memiliki jenis terkelola ke daftar parameter ekspresi lambda. Contoh berikut berisi ekspresi lambda yang mengambil variabel ch tidak terkelola lokal berdasarkan nilai dan mengambil System.String objek sebagai parameternya.

// 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");
}

Contoh menghasilkan output ini:

Hello!

Keterangan

Anda juga dapat menggunakan ekspresi lambda dengan pustaka STL/CLR. Untuk informasi selengkapnya, lihat Referensi Pustaka STL/CLR.

Penting

Lambda tidak didukung dalam entitas terkelola common language runtime (CLR) ini: ref class, , ref struct, value classdan value struct.

[Dalam artikel ini]

Lihat juga

Ekspresi Lambda
Sintaks Ekspresi Lambda
auto
function Kelas
find_if
<algorithm>
Panggilan Fungsi
Templat
Penanganan Pengecualian
Referensi Pustaka STL/CLR