C++ Academy · Ders

Çağrılabilir Ögeleri Seçme

Lambdaları, bind'i ve işaretçileri karşılaştırın

4. ders / 413 adım

Çağrılabilir Ögeleri Seçme, CoddyKit'te ücretsiz bir C++ Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C++ Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C++ Academy kursu toplamda 4 dersten oluşur.

Çağrılabilir Araç Kutusu

C++, davranışı aktarmak için çeşitli yollar sunar: işlev işaretçileri, lambda ifadeleri, işlev nesneleri, std::bind ve std::function. Her biri farklı ihtiyaçlara uygundur.

  • Hız ile esneklik arasındaki denge genellikle belirleyicidir.
  • Okunabilirlik de önemlidir.
#include <iostream>

int twice(int x) { return x * 2; }

int main() {
    int (*fp)(int) = twice;
    auto lam = [](int x) { return x * 2; };
    std::cout << fp(5) << ' ' << lam(5) << '\n';
    return 0;
}

İşlev İşaretçisi Ne Zaman Kullanılır?

Küçük, durum taşımayan bir geri çağrıya ve C uyumluluğuna veya sıfır ek yüke ihtiyaç duyduğunuzda işlev işaretçisini tercih edin.

#include <iostream>

void logMsg(const char* m) { std::cout << "LOG: " << m << '\n'; }

int main() {
    void (*handler)(const char*) = logMsg;
    handler("started");
    return 0;
}

Lambda İfadesi Ne Zaman Kullanılır?

Lambda ifadesi, modern varsayılan tercihtir: kısadır, durum yakalayabilir ve derleyici onu şablonlarda ve algoritmalarda satır içine başarıyla yerleştirir.

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

int main() {
    std::vector<int> v = {3, 1, 4, 1, 5};
    std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
    for (int x : v) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Bir Lambda İfadesinde Durum Yakalama

Lambda ifadeleri çevredeki değişkenleri yakalar; işlev işaretçileri bunu yapamaz. Bu nedenle lambda ifadeleri bağlama duyarlı geri çağrılar için idealdir.

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

int main() {
    int threshold = 3;
    std::vector<int> v = {1, 2, 3, 4, 5};
    int c = std::count_if(v.begin(), v.end(), [threshold](int x) { return x > threshold; });
    std::cout << c << '\n';
    return 0;
}

İşlev Nesnesi Ne Zaman Kullanılır?

operator() içeren bir yapı olan işlev nesnesi, yapılandırma tutabilen ve birçok yerde kullanılabilen, yeniden kullanılabilir ve adlandırılmış bir işlem için uygundur.

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

struct AboveThreshold {
    int limit;
    bool operator()(int x) const { return x > limit; }
};

int main() {
    std::vector<int> v = {1, 5, 2, 8};
    std::cout << std::count_if(v.begin(), v.end(), AboveThreshold{4}) << '\n';
    return 0;
}

Lambda İfadesi ve bind

Her ikisi de bağımsız değişkenleri önceden doldurabilir. Lambda ifadesi sürümü genellikle daha açıktır ve derleyicinin en iyi duruma getirmesi daha kolaydır; bu nedenle std::bind yerine onu tercih edin.

#include <iostream>

int power(int base, int exp) {
    int r = 1;
    for (int i = 0; i < exp; ++i) r *= base;
    return r;
}

int main() {
    auto square = [](int x) { return power(x, 2); };
    std::cout << square(6) << '\n';
    return 0;
}

std::function Ne Zaman Kullanılır?

Belirli somut türü bilinmeyen bir çağrılabilir nesneyi, örneğin bir sınıf üyesinde veya kapsayıcıda saklamanız gerektiğinde std::function kullanın.

#include <iostream>
#include <functional>
#include <vector>

int main() {
    std::vector<std::function<int(int)>> pipeline;
    pipeline.push_back([](int x) { return x + 1; });
    pipeline.push_back([](int x) { return x * 3; });
    int v = 2;
    for (auto& f : pipeline) v = f(v);
    std::cout << v << '\n';
    return 0;
}

Şablonlar Ek Yükü Önler

Bir işlevin yalnızca bir çağrılabilir nesneyi alması gerekiyorsa (onu saklamıyorsa), şablon parametresi tür silmeyi önleyerek tam hızı korur.

#include <iostream>

template <typename F>
int applyTwice(int x, F f) { return f(f(x)); }

int main() {
    std::cout << applyTwice(3, [](int n) { return n + 10; }) << '\n';
    return 0;
}

Başarım Sıralaması

Yaklaşık olarak: şablonla oluşturulmuş bir çağrılabilir nesne veya yakalama yapmayan bir lambda ifadesi en hızlıdır, işlev işaretçisi buna yakındır ve std::function dolaylı çağrı ve olası bellek ayırma nedeniyle en yavaştır.

#include <iostream>
#include <functional>

int main() {
    auto fast = [](int x) { return x + 1; };
    std::function<int(int)> flexible = fast;
    std::cout << fast(1) << ' ' << flexible(1) << '\n';
    return 0;
}

Karar Rehberi

Kısa rehber:

  • Herhangi bir çağrılabilir nesneyi saklamanız mı gerekiyor? std::function.
  • Genel bir işlevde yalnızca bir çağrılabilir nesne almanız mı gerekiyor? Şablon parametresi.
  • Durum içeren satır içi davranış mı gerekiyor? Lambda ifadesi.
  • C API'si veya durum taşımayan bir yapı mı gerekiyor? İşlev işaretçisi.
#include <iostream>
#include <functional>

void runStored(const std::function<void()>& cb) { cb(); }

template <typename F>
void runGeneric(F f) { f(); }

int main() {
    runStored([] { std::cout << "stored\n"; });
    runGeneric([] { std::cout << "generic\n"; });
    return 0;
}

Hepsini Bir Araya Getirme

Küçük bir olay sistemi, işleyicileri genel olarak alabilir; ancak daha sonra çağrılabilmeleri için onları std::function içinde saklayabilir.

#include <iostream>
#include <functional>
#include <vector>

struct Dispatcher {
    std::vector<std::function<void(int)>> handlers;
    template <typename F> void on(F f) { handlers.emplace_back(f); }
    void fire(int e) { for (auto& h : handlers) h(e); }
};

int main() {
    Dispatcher d;
    d.on([](int e) { std::cout << "got " << e << '\n'; });
    d.fire(7);
    return 0;
}

Kısa Kontrol

Çağrılabilir nesne seçimi hakkındaki anlayışınızı sınayın.

Özet

Bir çağrılabilir nesneyi nasıl seçeceğinizi öğrendiniz:

  • Durum taşımayan ve C ile uyumlu geri çağrılar için işlev işaretçisi
  • Satır içi, durum içeren davranış için varsayılan tercih olarak lambda ifadesi
  • Yeniden kullanılabilir, adlandırılmış işlemler için işlev nesnesi
  • Yalnızca çağrılabilir nesne alındığında (en hızlı seçenek) şablon parametresi
  • Türü bilinmeyen bir çağrılabilir nesneyi saklamanız gerektiğinde std::function

İşlev Nesneleri ve std::bind kursu böylece tamamlanır.

Başlamak ücretsiz

Yapay zeka eğitmeniyle C++ öğren — ücretsiz

Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.

Kurslar
51
Dersler
203

Sıkça Sorulan Sorular

“Çağrılabilir Ögeleri Seçme” dersi ücretsiz mi?

Evet — “Çağrılabilir Ögeleri Seçme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C++ Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C++ Academy kursu toplamda 4 dersten oluşur.

“Çağrılabilir Ögeleri Seçme” dersinde ne öğreneceğim?

Lambdaları, bind'i ve işaretçileri karşılaştırın C++ Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

C++ Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te C++ Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.

“Çağrılabilir Ögeleri Seçme” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu C++ Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her C++ Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. İşlev İşaretçileri
  2. std::function
  3. std::bind
  4. Çağrılabilir Ögeleri Seçme
← C++ Academy Sayfasına Dön