Aufrufbare Objekte auswählen
Lambdas, bind oder Zeiger
Aufrufbare Objekte auswählen ist eine kostenlose C++ Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C++ Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C++ Academy-Kurs umfasst insgesamt 4 Lektionen.
Der Werkzeugkasten für aufrufbare Objekte
C++ bietet mehrere Möglichkeiten, Verhalten weiterzugeben: Funktionszeiger, Lambdas, Funktoren, std::bind und std::function. Jedes eignet sich für unterschiedliche Anforderungen.
- Geschwindigkeit und Flexibilität stehen üblicherweise in einem Spannungsverhältnis.
- Auch die Lesbarkeit ist wichtig.
#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;
}Wann Sie einen Funktionszeiger verwenden sollten
Verwenden Sie einen Funktionszeiger, wenn Sie einen kleinen, zustandslosen Callback benötigen und C-Kompatibilität oder keinen zusätzlichen Laufzeitaufwand wünschen.
#include <iostream>
void logMsg(const char* m) { std::cout << "LOG: " << m << '\n'; }
int main() {
void (*handler)(const char*) = logMsg;
handler("started");
return 0;
}Wann Sie ein Lambda verwenden sollten
Ein Lambda ist die moderne Standardwahl: Es ist kompakt, kann Zustand erfassen und wird vom Compiler in Templates und Algorithmen gut inline eingesetzt.
#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;
}Zustand in einem Lambda erfassen
Lambdas erfassen Variablen aus ihrer Umgebung – etwas, das Funktionszeiger nicht können. Dadurch eignen sie sich ideal für kontextabhängige Callbacks.
#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;
}Wann Sie einen Funktor verwenden sollten
Ein Funktor (eine Struktur mit operator()) eignet sich für eine wiederverwendbare, benannte Operation, die Konfiguration enthalten und an vielen Stellen verwendet werden kann.
#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 oder Bind
Beide können Argumente vorab belegen. Die Lambda-Variante ist normalerweise verständlicher und lässt sich vom Compiler leichter optimieren. Bevorzugen Sie sie daher gegenüber std::bind.
#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;
}Wann Sie std::function verwenden sollten
Verwenden Sie std::function, wenn Sie ein aufrufbares Objekt mit unbekanntem konkretem Typ speichern müssen, zum Beispiel als Klassenmember oder in einem Container.
#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;
}Templates vermeiden zusätzlichen Aufwand
Wenn eine Funktion ein aufrufbares Objekt nur entgegennehmen und nicht speichern muss, sorgt ein Template-Parameter für maximale Geschwindigkeit, da die Typlöschung vermieden wird.
#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;
}Leistungsvergleich
Ungefähr gilt: Ein aufrufbares Objekt aus einem Template oder ein Lambda ohne Erfassung ist am schnellsten, ein Funktionszeiger liegt nur knapp dahinter, und std::function ist wegen der Indirektion und einer möglichen Speicherreservierung am langsamsten.
#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;
}Eine Entscheidungshilfe
Kurze Entscheidungshilfe:
- Müssen Sie ein beliebiges aufrufbares Objekt speichern?
std::function. - Nehmen Sie ein solches Objekt nur in einer generischen Funktion entgegen? Template-Parameter.
- Benötigen Sie Inline-Verhalten mit Zustand? Lambda.
- C-API oder zustandslos? Funktionszeiger.
#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;
}Alles zusammenführen
Ein kleines Ereignissystem könnte Handler generisch entgegennehmen, sie aber in std::function speichern, damit sie später aufgerufen werden können.
#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;
}Schnelltest
Testen Sie Ihr Verständnis der Auswahl aufrufbarer Objekte.
Zusammenfassung
Sie haben gelernt, wie Sie ein aufrufbares Objekt auswählen:
- Funktionszeiger für zustandslose, C-kompatible Callbacks
- Lambda als Standard für Inline-Verhalten mit Zustand
- Funktor für wiederverwendbare, benannte Operationen
- Template-Parameter, wenn ein aufrufbares Objekt nur entgegengenommen wird (am schnellsten)
std::function, wenn Sie ein Objekt mit unbekanntem Typ speichern müssen
Damit ist der Kurs zu Funktionsobjekten und std::bind abgeschlossen.
Häufig gestellte Fragen
Ist die Lektion „Aufrufbare Objekte auswählen“ kostenlos?
Ja — der vollständige Text von „Aufrufbare Objekte auswählen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C++ Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C++ Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Aufrufbare Objekte auswählen“?
Lambdas, bind oder Zeiger Du übst C++ Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C++ Academy zu starten?
Keine Vorkenntnisse erforderlich. C++ Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.
Wie lange dauert die Lektion „Aufrufbare Objekte auswählen“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C++ Academy-Lektion Code schreiben und ausführen?
Ja. Jede C++ Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Funktionszeiger
- std::function
- std::bind
- Aufrufbare Objekte auswählen