Menu
CoddyTech

Functor dan Ekspresi Lambda

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 74 dari 104.

Banyak algoritma STL menerima object yang dapat dipanggil untuk menyesuaikan perilakunya. Kamu sudah melihat lambda digunakan dengan std::transform. Mari kita pelajari functor dan ekspresi lambda, dua cara untuk membuat object yang dapat dipanggil di C++.

functor (object fungsi) adalah class yang melakukan overload pada operator(), sehingga instansnya dapat dipanggil seperti fungsi:

#include <algorithm>
#include <vector>
#include <iostream>

struct MultiplyBy {
    int factor;
    MultiplyBy(int f) : factor(f) {}
    
    int operator()(int x) const {
        return x * factor;
    }
};

int main() {
    std::vector<int> nums = {1, 2, 3, 4};
    std::vector<int> result(nums.size());
    
    std::transform(nums.begin(), nums.end(), result.begin(), MultiplyBy(3));
    // result: {3, 6, 9, 12}
}

Setiap instance functor dapat membawa state independennya sendiri melalui variabel anggota yang ditetapkan saat konstruksi, sesuatu yang tidak dapat dilakukan oleh pemanggilan fungsi biasa. Namun, mendefinisikan class untuk operasi sederhana terasa bertele-tele. Ekspresi lambda menyediakan alternatif yang ringkas:

int factor = 3;
std::transform(nums.begin(), nums.end(), result.begin(),
               [factor](int x) { return x * factor; });

Sintaks lambda adalah [capture](parameters) { body }. Klausa capture menentukan variabel di luar mana yang dapat diakses lambda. Gunakan [=] untuk menangkap semua variabel berdasarkan nilai, [&] untuk menangkap semua variabel berdasarkan referensi, atau cantumkan variabel tertentu seperti [factor] atau [&factor].

Lambdas sangat berguna untuk operasi sekali pakai dengan algoritma seperti pengurutan menggunakan kriteria khusus:

std::vector<int> nums = {5, -2, 8, -1};
std::sort(nums.begin(), nums.end(), 
          [](int a, int b) { return std::abs(a) < std::abs(b); });
// Diurutkan berdasarkan nilai mutlak: {-1, -2, 5, 8}
challenge icon

Tantangan

Mudah

Mari buat kalkulator harga yang menunjukkan cara menggunakan functor dan ekspresi lambda untuk menerapkan berbagai strategi diskon pada harga produk.

Kamu akan mengatur kodemu dalam dua file:

  • Discounts.h: Definisikan functor diskon dan fungsi utilitasmu di sini.

    Buat functor bernama PercentageDiscount yang menyimpan persentase diskon sebagai bilangan bulat. operator()-nya harus menerima harga bertipe double dan mengembalikan harga setelah diskon. Misalnya, diskon 20% untuk $100 harus menghasilkan $80.

    Buat functor lain bernama FixedDiscount yang menyimpan jumlah tetap yang akan dikurangi, bertipe double. operator()-nya harus menerima harga dan mengembalikan harga dikurangi jumlah tetap tersebut, tetapi hasilnya tidak boleh kurang dari 0.

    Buat fungsi bernama printPrices yang menerima const std::vector<double>& dan mencetak semua harga yang dipisahkan oleh spasi, diikuti baris baru. Format setiap harga dengan dua angka di belakang koma.

  • main.cpp: Baca lima input, masing-masing pada baris terpisah:
    1. Harga produk pertama (double)
    2. Harga produk kedua (double)
    3. Harga produk ketiga (double)
    4. Persentase diskon yang diterapkan (bilangan bulat, misalnya 20 untuk 20%)
    5. Jumlah diskon tetap (double)

    Buat vector berisi ketiga harga tersebut dan tunjukkan kedua pendekatan:

    1. Cetak Original prices: diikuti harga-harganya
    2. Gunakan std::transform dengan functor PercentageDiscount-mu untuk membuat vector baru yang berisi harga setelah diskon. Cetak After percentage discount: diikuti hasilnya
    3. Gunakan std::transform dengan functor FixedDiscount-mu pada harga asli untuk membuat vector lain. Cetak After fixed discount: diikuti hasilnya
    4. Gunakan std::transform dengan ekspresi lambda yang menggandakan setiap harga asli. Cetak Premium prices (doubled): diikuti hasilnya
    5. Gunakan std::sort dengan lambda untuk mengurutkan harga asli secara menurun. Cetak Sorted (high to low): diikuti harga yang sudah diurutkan

Misalnya, dengan input 100.00, 50.00, 75.00, 20, dan 15.00:

Original prices: 100.00 50.00 75.00 
After percentage discount: 80.00 40.00 60.00 
After fixed discount: 85.00 35.00 60.00 
Premium prices (doubled): 200.00 100.00 150.00 
Sorted (high to low): 100.00 75.00 50.00 

Tantangan ini memungkinkan kamu membandingkan functor, yang mempertahankan state seperti jumlah diskon, dengan lambda, yang menangkap variabel untuk operasi singkat langsung di tempat. Keduanya dapat digunakan dengan lancar bersama algoritma STL seperti std::transform dan std::sort.

Coba sendiri

#include <iostream>
#include <vector>
#include <algorithm>
#include "Discounts.h"

int main() {
    // Baca input
    double price1, price2, price3;
    int percentageDiscount;
    double fixedDiscount;
    
    std::cin >> price1;
    std::cin >> price2;
    std::cin >> price3;
    std::cin >> percentageDiscount;
    std::cin >> fixedDiscount;
    
    // Buat vector berisi ketiga harga
    std::vector<double> prices = {price1, price2, price3};
    
    // TODO: Cetak "Original prices:" lalu cetak harga menggunakan printPrices
    
    // TODO: Gunakan std::transform dengan functor PercentageDiscount
    // Buat vector baru untuk hasilnya
    // Cetak "After percentage discount:" lalu cetak hasilnya
    
    // TODO: Gunakan std::transform dengan functor FixedDiscount pada harga asli
    // Buat vector baru untuk hasilnya
    // Cetak "After fixed discount:" lalu cetak hasilnya
    
    // TODO: Gunakan std::transform dengan lambda yang menggandakan setiap harga asli
    // Buat vector baru untuk hasilnya
    // Cetak "Premium prices (doubled):" lalu cetak hasilnya
    
    // TODO: Gunakan std::sort dengan lambda untuk mengurutkan harga asli dari yang tertinggi ke terendah
    // Cetak "Sorted (high to low):" lalu cetak harga yang sudah diurutkan
    
    return 0;
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler C++ online