Menu
CoddyTech

std::function & std::bind

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

Meskipun lambda sangat berguna, terkadang kamu perlu menyimpan object yang dapat dipanggil dengan tipe berbeda secara seragam, atau menyesuaikan fungsi yang sudah ada agar cocok dengan signature yang diperlukan. std::function dan std::bind dari header <functional> mengatasi masalah ini.

std::function adalah pembungkus dengan tipe yang dihapus, yang dapat menyimpan callable apa pun yang cocok dengan tanda tangan tertentu, seperti fungsi, lambda, atau object fungsi:

#include <iostream>
#include <functional>

int add(int a, int b) { return a + b; }

int main() {
    std::function<int(int, int)> operation;
    
    operation = add;                              // Fungsi biasa
    std::cout << operation(3, 4) << "\n";        // 7
    
    operation = [](int a, int b) { return a * b; }; // Lambda
    std::cout << operation(3, 4) << "\n";        // 12
}

std::bind membuat objek callable baru dengan menetapkan beberapa argumen dari fungsi yang sudah ada. Gunakan std::placeholders::_1, _2, dan seterusnya untuk menandai argumen yang tetap variabel:

#include <iostream>
#include <functional>

void greet(const std::string& greeting, const std::string& name) {
    std::cout << greeting << ", " << name << "!\n";
}

int main() {
    using namespace std::placeholders;
    
    auto sayHello = std::bind(greet, "Hello", _1);
    sayHello("Alice");  // Hello, Alice!
    
    auto swapped = std::bind(greet, _2, _1);
    swapped("Bob", "Hi");  // Hi, Bob!
}

Alat-alat ini sangat berguna dalam OOP untuk menyimpan callback sebagai anggota class atau menerapkan pola Strategy. Namun, C++ modern sering lebih memilih lambda daripada std::bind karena lebih mudah dibaca dan lebih efisien. Gunakan std::bind terutama saat kamu perlu mengubah urutan argumen atau bekerja dengan kode lama.

challenge icon

Tantangan

Mudah

Mari buat kalkulator yang dapat dikonfigurasi untuk menunjukkan keunggulan std::function dan std::bind. Kamu akan membuat sistem yang dapat menyimpan, menukar, dan menyesuaikan operasi matematika saat program berjalan: sistem ini menunjukkan cara alat tersebut memungkinkan pengelolaan callback yang fleksibel.

Kamu akan mengatur kodemu dalam tiga file:

  • MathOperations.h: Definisikan kumpulan fungsi matematika mandiri yang akan menjadi library operasimu.

    Buat fungsi-fungsi ini:

    • add(int a, int b): mengembalikan hasil penjumlahan
    • subtract(int a, int b): mengembalikan hasil pengurangan (a - b)
    • multiply(int a, int b): mengembalikan hasil perkalian
    • power(int base, int exponent, int multiplier): mengembalikan multiplier * (base ^ exponent). Gunakan perulangan sederhana untuk menghitung pangkatnya (anggap eksponennya tidak negatif).
  • Calculator.h: Definisikan class Calculator yang menggunakan std::function untuk menyimpan dan menjalankan operasi secara dinamis.

    Calculator-mu harus memiliki:

    • Member privat std::function<int(int, int)> untuk menyimpan operasi biner saat ini
    • setOperation(std::function<int(int, int)> op): menetapkan operasi saat ini
    • calculate(int a, int b): menjalankan operasi yang tersimpan dan mengembalikan hasilnya

    Sertakan header yang diperlukan (<functional>) dan pastikan untuk menyertakan header MathOperations-mu.

  • main.cpp: Baca tiga input:
    1. Nama operasi: add, subtract, multiply, atau square
    2. Bilangan pertama (bilangan bulat)
    3. Bilangan kedua (bilangan bulat)

    Buat Calculator dan konfigurasikan berdasarkan nama operasi:

    • Untuk add, subtract, dan multiply: tetapkan fungsi yang sesuai secara langsung ke calculator
    • Untuk square: gunakan std::bind untuk membuat versi khusus dari power yang selalu menggunakan eksponen 2 dan pengali 1. Fungsi yang diikat harus menerima dua argumen, dengan hanya argumen pertama yang digunakan sebagai basis (argumen kedua dapat diabaikan menggunakan placeholder).

    Setelah menetapkan operasi, panggil calculate() dengan kedua bilanganmu dan cetak:

    Result: [value]

    Lalu tunjukkan cara menukar operasi dengan menetapkan lambda yang mengembalikan a + b + 100 ke calculator, menjalankannya dengan input yang sama, lalu mencetak:

    With bonus: [value]

Contohnya, dengan input add, 10, dan 5:

Result: 15
With bonus: 115

Dengan input multiply, 7, dan 3:

Result: 21
With bonus: 110

Dengan input square, 4, dan 0:

Result: 16
With bonus: 104

Tantangan ini menunjukkan cara std::function menyediakan cara seragam untuk menyimpan berbagai tipe callable (fungsi biasa, fungsi yang diikat, dan lambda), sementara std::bind memungkinkanmu menyesuaikan fungsi yang sudah ada dengan menetapkan beberapa argumennya.

Coba sendiri

#include <iostream>
#include <string>
#include <functional>
#include "Calculator.h"

using namespace std;

int main() {
    // Baca input
    string operation;
    int num1, num2;
    cin >> operation >> num1 >> num2;
    
    // Buat instance Calculator
    Calculator calc;
    
    // TODO: Konfigurasikan kalkulator berdasarkan nama operasi
    // Untuk "add", "subtract", "multiply": tetapkan fungsi yang sesuai secara langsung
    // Untuk "square": gunakan std::bind untuk membuat versi khusus dari power
    //   yang selalu menggunakan eksponen 2 dan pengali 1
    //   Petunjuk: Gunakan std::placeholders::_1 untuk argumen basis
    
    if (operation == "add") {
        // Tulis kodemu di sini
    } else if (operation == "subtract") {
        // Tulis kodemu di sini
    } else if (operation == "multiply") {
        // Tulis kodemu di sini
    } else if (operation == "square") {
        // Tulis kodemu di sini, gunakan std::bind dengan fungsi power
    }
    
    // TODO: Panggil calculate() dan tampilkan hasilnya
    // Format: "Result: [value]"
    
    // TODO: Tunjukkan cara mengganti operasi
    // Tetapkan lambda yang mengembalikan a + b + 100 ke kalkulator
    // Panggil calculate() lagi dan cetak hasilnya
    // Format: "With bonus: [value]"
    
    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