Blog 3 min de lecture

Modern C++ Design : apprenez avec la bibliothèque Loki

Share this article
Modern C++ Design : apprenez avec la bibliothèque Loki

Si vous décidez de vous lancer dans l'apprentissage de la conception moderne en C++ et que vous venez de l'école de la POO, vous pouvez commencer par explorer la bibliothèque Loki .

Loki est le nom d'une bibliothèque logicielle C++ écrite par Andrei Alexandrescu dans le cadre de son livre Modern C++ Design.

. La bibliothèque fait un usage intensif de la métaprogrammation par templates C++ et implémente plusieurs outils couramment utilisés : listes de types (typelists), foncteurs, singletons, pointeurs intelligents, fabriques d'objets, visiteurs et multiméthodes.

Voici la motivation de l'auteur derrière la conception de cette bibliothèque :

  • Les utilisateurs de Loki ne paient que pour les fonctionnalités qu'ils souhaitent. Chacun des composants de Loki peut être utilisé indépendamment des autres.
  • « Small is beautiful » (la petitesse est une qualité) — les dépendances internes de Loki sont réduites.
  • « Multiplicative is splendid » (la multiplicativité est splendide) — Loki se concentre particulièrement sur l'obtention de comportements multiplicatifs (c'est-à-dire des conceptions fines et spécialisées), en combinant de petites briques de comportement abstraites (les politiques).
  • Loki se concentre sur la stratégie, pas la tactique ; sur la conception, pas les bits ; sur les composants architecturaux, pas sur la cuisine complète.
  • Comme Loki est une bibliothèque de conceptions et non la conception d'une bibliothèque, elle devrait faire un minimum d'hypothèses sur son environnement et fournir des points d'ancrage appropriés partout où une décision par défaut est choisie.
  • Loki ne fait pas de concessions aux compilateurs moins capables. Loki vise à écrire du code lisible dans le cadre du C++ standard.
  • Les composants sont idéalement petits, faciles à comprendre et à utiliser correctement, utiles aussi bien isolément qu'ensemble, et à fort impact dans les projets.

Mais avant de plonger plus profondément dans ses idiomes C++ modernes, il est préférable de maîtriser un concept central de la programmation par templates : l'idiome de conception basée sur les politiques (policy-based design).

L'idiome central de la conception basée sur les politiques est un template de classe (appelé classe hôte), prenant plusieurs paramètres de type en entrée, qui sont instanciés avec des types choisis par l'utilisateur (appelés classes de politique), chacun implémentant une interface implicite particulière (appelée politique), et encapsulant un aspect orthogonal (ou presque orthogonal) du comportement de la classe hôte instanciée. En fournissant une classe hôte combinée à un ensemble d'implémentations prêtes à l'emploi pour chaque politique, une bibliothèque ou un module peut prendre en charge un nombre exponentiel de combinaisons de comportements différentes, résolues à la compilation, et choisies en mixant les différentes classes de politique fournies lors de l'instanciation du template de la classe hôte.

Voici un petit exemple issu de Wikipédia illustrant cet idiome utile :

#include 
#include 
 
template 
class HelloWorld : private OutputPolicy, private LanguagePolicy
{
    using OutputPolicy::print;
    using LanguagePolicy::message;
 
public:
    // Behaviour method
    void run() const
    {
        // Two policy methods
        print(message());
    }
};
 
class OutputPolicyWriteToCout
{
protected:
    template
    void print(MessageType const &message) const
    {
        std::cout << message << std::endl;
    }
};
 
class LanguagePolicyEnglish
{
protected:
    std::string message() const
    {
        return "Hello, World!";
    }
};
 
class LanguagePolicyGerman
{
protected:
    std::string message() const
    {
        return "Hallo Welt!";
    }
};
 
int main()
{
    /* Example 1 */
    typedef HelloWorld<OutputPolicyWriteToCout, LanguagePolicyEnglish> HelloWorldEnglish;
 
    HelloWorldEnglish hello_world;
    hello_world.run(); // prints "Hello, World!"
 
    /* Example 2 
     * Does the same, but uses another language policy */
    typedef HelloWorld<OutputPolicyWriteToCout, LanguagePolicyGerman> HelloWorldGerman;
 
    HelloWorldGerman hello_world2;
    hello_world2.run(); // prints "Hallo Welt!"
}

Après avoir découvert la conception basée sur les politiques, vous pouvez passer aux autres idiomes utilisés par la bibliothèque :

  • Répartiteur multiple (multiple dispatcher)
  • Pimpl
  • Printf (un remplacement de printf à typage sûr)
  • Création ordonnée d'objets statiques
  • Pointeur de garde de portée (scope guard pointer)
  • Allocateur de petits objets (small object allocator)
  • Pointeur intelligent
  • Vérification à la compilation

Vous pouvez obtenir une explication détaillée des idiomes ci-dessus dans cette ressource.

Pour résumer, la bibliothèque Loki n'est pas aussi populaire que la STL ou Boost, mais c'est une bibliothèque pédagogique intéressante pour apprendre les idiomes de base de la conception C++ moderne. C'est un bon point de départ pour maîtriser la conception C++ moderne.

Share this article