Menu
Coddy logo textTech

std::function ve std::bind

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 86 / 104.

Lambda'lar güçlü olsa da bazen farklı türlere sahip çağrılabilir nesneleri tekdüze bir şekilde depolamanız veya mevcut işlevleri gereken imzayla eşleşecek şekilde uyarlamanız gerekir. std::function ve std::bind, <functional> başlığından bu sorunları çözer.

std::function, belirli bir imzayla eşleşen herhangi bir çağrılabilir öğeyi (fonksiyonlar, lambda'lar veya fonksiyon nesneleri) tutabilen, tür silme kullanan bir sarmalayıcıdır:

#include <iostream>
#include <functional>

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

int main() {
    std::function<int(int, int)> operation;
    
    operation = add;                              // Normal fonksiyon
    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, mevcut bir işlevin bazı bağımsız değişkenlerini sabitleyerek yeni bir çağrılabilir oluşturur. Değişken kalacak bağımsız değişkenleri işaretlemek için std::placeholders::_1, _2 vb. kullanın:

#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");  // Merhaba, Alice!
    
    auto swapped = std::bind(greet, _2, _1);
    swapped("Bob", "Hi");  // Selam, Bob!
}

Bu araçlar, geri çağırmaları sınıf üyeleri olarak depolamak veya Strateji desenini uygulamak için OOP'de özellikle kullanışlıdır. Ancak modern C++ daha iyi okunabilirlik ve performans için genellikle std::bind yerine lambda ifadelerini tercih eder; std::bindi esas olarak bağımsız değişkenlerin sırasını değiştirmeniz veya eski kodla çalışmanız gerektiğinde kullanın.

challenge icon

Görev

Kolay

std::function ve std::bind gücünü Demonstrate eden yapılandırılabilir bir calculator oluşturalım. Matematiksel işlemlerin çalışma zamanında depolanabildiği, değiştirilebildiği ve özelleştirilebildiği bir sistem oluşturacaksın: bu araçların esnek callback yönetimini nasıl mümkün kıldığını göreceksin.

Codenu üç dosyada düzenleyeceksin:

  • MathOperations.h: İşlem kitaplığın olarak hizmet edecek bağımsız matematik function koleksiyonu Declare et.

    Bu functionları Create et:

    • add(int a, int b): toplamı döndürür
    • subtract(int a, int b): difference döndürür (a - b)
    • multiply(int a, int b): çarpımı döndürür
    • power(int base, int exponent, int multiplier): multiplier * (base ^ exponent) döndürür. Üssü hesaplamak için basit bir döngü kullan (exponent değerlerinin negatif olmadığını assume et).
  • Calculator.h: İşlemleri dinamik olarak depolamak ve Execute etmek için std::function kullanan bir Calculator classı define et.

    Calculator'ın şunlara sahip olmalı:

    • current ikili işlemi depolamak için private bir std::function<int(int, int)> üye
    • setOperation(std::function<int(int, int)> op): current işlemi ayarlar
    • calculate(int a, int b): depolanan işlemi Executes eder ve sonucu döndürür

    Gerekli başlıkları (<functional>) include et ve MathOperations başlığını include ettiğinden emin ol.

  • main.cpp: Üç input oku:
    1. İşlem adı: add, subtract, multiply veya square
    2. first sayı (integer)
    3. İkinci sayı (integer)

    Bir Calculator Create et ve işlem adına göre Configure et:

    • add, subtract ve multiply için: corresponding functionı directly calculator'a assign et
    • square için: her zaman exponent olarak 2 ve multiplier olarak 1 kullanan özelleştirilmiş bir power sürümü Create etmek için std::bind kullan. Bound function iki argument kabul etmeli; bunlardan yalnızca first olan base olarak kullanılmalı (ikinci argument bir placeholder kullanılarak yok sayılabilir).

    İşlemi ayarladıktan sonra iki sayınla calculate() Call et ve şunu yazdır:

    Result: [value]

    Ardından calculator'a a + b + 100 döndüren bir lambda assign ederek, aynı inputlerle çalıştırıp şunu yazdırarak işlemleri değiştirmeyi Demonstrate et:

    With bonus: [value]

Örneğin inputler add, 10 ve 5 olduğunda:

Result: 15
With bonus: 115

Inputler multiply, 7 ve 3 olduğunda:

Result: 21
With bonus: 110

Inputler square, 4 ve 0 olduğunda:

Result: 16
With bonus: 104

Bu challenge, std::function'ın farklı çağrılabilir türleri (normal functionlar, bound functionlar ve lambdalar) depolamak için nasıl uniform bir yol sağladığını; std::bind'in ise bazı argumentlarını sabitleyerek mevcut functionları uyarlamana nasıl olanak tanıdığını gösterir.

Kendin dene

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

using namespace std;

int main() {
    // Girdileri oku
    string operation;
    int num1, num2;
    cin >> operation >> num1 >> num2;
    
    // Bir Calculator örneği oluştur
    Calculator calc;
    
    // TODO: Hesap makinesini işlem adına göre yapılandır
    // "add", "subtract", "multiply" için: ilgili fonksiyonu doğrudan ata
    // "square" için: power'ın özelleştirilmiş bir sürümünü oluşturmak için std::bind kullan
    //   her zaman üs 2 ve çarpan 1 kullanan
    //   İpucu: Taban argümanı için std::placeholders::_1 kullan
    
    if (operation == "add") {
        // Kodunuz buraya
    } else if (operation == "subtract") {
        // Kodunuz buraya
    } else if (operation == "multiply") {
        // Kodunuz buraya
    } else if (operation == "square") {
        // Kodunuz buraya - power fonksiyonu ile std::bind kullan
    }
    
    // TODO: calculate() çağır ve sonucu yazdır
    // Biçim: "Result: [value]"
    
    // TODO: İşlem değiştirmeyi göster
    // Hesap makinesine a + b + 100 döndüren bir lambda ata
    // calculate() fonksiyonunu tekrar çağır ve sonucu yazdır
    // Biçim: "With bonus: [value]"
    
    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online C++ derleyicisi