C++ Academy · Leçon

Choisir des appelables

Lambdas, bind ou pointeurs

Leçon 4 sur 413 étapes

Choisir des appelables est une leçon C++ Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C++ Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C++ Academy comprend 4 leçons au total.

La boîte à outils des objets appelables

Le C++ offre plusieurs moyens de transmettre un comportement : les pointeurs de fonction, les lambdas, les foncteurs, std::bind et std::function. Chacun répond à des besoins différents.

  • Le compromis habituel oppose rapidité et flexibilité.
  • La lisibilité compte également.
#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;
}

Quand utiliser un pointeur de fonction

Choisissez un pointeur de fonction lorsque vous avez besoin d'une petite fonction de rappel sans état et que vous voulez une compatibilité avec le C ou l'absence de surcharge.

#include <iostream>

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

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

Quand utiliser une lambda

Une lambda est le choix moderne par défaut : elle est concise, peut capturer un état et le compilateur l'intègre efficacement dans les modèles et les algorithmes.

#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;
}

Capturer un état dans une lambda

Les lambdas capturent les variables environnantes, ce que les pointeurs de fonction ne peuvent pas faire, ce qui les rend idéales pour les fonctions de rappel tenant compte du contexte.

#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;
}

Quand utiliser un foncteur

Un foncteur (une structure avec operator()) convient à une opération nommée et réutilisable qui peut contenir une configuration et être utilisée à plusieurs endroits.

#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 ou bind

Les deux peuvent préremplir des arguments. La version utilisant une lambda est généralement plus claire et plus facile à optimiser pour le compilateur ; préférez-la donc à 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;
}

Quand utiliser std::function

Utilisez std::function lorsque vous devez stocker un objet appelable dont le type concret est inconnu, par exemple dans un membre de classe ou un conteneur.

#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;
}

Les modèles évitent la surcharge

Si une fonction doit seulement recevoir un objet appelable, sans le stocker, un paramètre de modèle conserve toutes les performances en évitant l'effacement de type.

#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;
}

Classement des performances

En gros : un objet appelable basé sur un modèle ou une lambda sans capture est le plus rapide, un pointeur de fonction arrive juste après, et std::function est le plus lent en raison de l'indirection et d'une allocation éventuelle.

#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;
}

Guide de décision

Guide rapide :

  • Vous devez stocker n'importe quel objet appelable ? std::function.
  • Vous devez simplement en recevoir un dans une fonction générique ? Un paramètre de modèle.
  • Vous voulez un comportement avec état défini sur place ? Une lambda.
  • Vous avez besoin d'une API C ou d'un objet sans état ? Un pointeur de fonction.
#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;
}

Tout assembler

Un petit système d'événements peut recevoir les gestionnaires de manière générique, puis les stocker dans std::function afin de pouvoir les invoquer plus tard.

#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;
}

Vérification rapide

Vérifiez votre compréhension du choix des objets appelables.

Récapitulatif

Vous avez appris à choisir un objet appelable :

  • pointeur de fonction pour les fonctions de rappel sans état et compatibles avec le C
  • lambda comme choix par défaut pour un comportement avec état défini sur place
  • foncteur pour les opérations nommées et réutilisables
  • paramètre de modèle lorsque vous devez seulement recevoir un objet appelable (solution la plus rapide)
  • std::function lorsque vous devez en stocker un dont le type est inconnu

Le cours sur les objets fonctionnels et std::bind est terminé.

Gratuit pour commencer

Apprends C++ avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
51
Leçons
203

Questions Fréquemment Posées

La leçon « Choisir des appelables » est-elle gratuite ?

Oui — le texte complet de « Choisir des appelables » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C++ Academy, passe à CoddyKit PRO. Le cours C++ Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Choisir des appelables » ?

Lambdas, bind ou pointeurs Tu pratiques C++ Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer C++ Academy ?

Aucune expérience préalable n'est requise. C++ Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Choisir des appelables » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon C++ Academy ?

Oui. Chaque leçon C++ Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Pointeurs de fonctions
  2. std::function
  3. std::bind
  4. Choisir des appelables
← Retour à C++ Academy