web-dev-qa-db-fra.com

CRTP pour éviter le polymorphisme dynamique

Comment puis-je utiliser CRTP en C++ pour éviter la surcharge des fonctions de membre virtuel?

87
Amit

Il y a deux façons.

La première consiste à spécifier statiquement l'interface pour la structure des types:

template <class Derived>
struct base {
  void foo() {
    static_cast<Derived *>(this)->foo();
  };
};

struct my_type : base<my_type> {
  void foo(); // required to compile.
};

struct your_type : base<your_type> {
  void foo(); // required to compile.
};

La seconde consiste à éviter l'utilisation de l'idiome référence à base ou pointeur à base et à effectuer le câblage au moment de la compilation. En utilisant la définition ci-dessus, vous pouvez avoir des fonctions de modèle qui ressemblent à celles-ci:

template <class T> // T is deduced at compile-time
void bar(base<T> & obj) {
  obj.foo(); // will do static dispatch
}

struct not_derived_from_base { }; // notice, not derived from base

// ...
my_type my_instance;
your_type your_instance;
not_derived_from_base invalid_instance;
bar(my_instance); // will call my_instance.foo()
bar(your_instance); // will call your_instance.foo()
bar(invalid_instance); // compile error, cannot deduce correct overload

Ainsi, la combinaison de la définition de la structure/interface et de la déduction de type au moment de la compilation dans vos fonctions vous permet d'effectuer une répartition statique au lieu d'une répartition dynamique. C'est l'essence du polymorphisme statique.

135
Dean Michael

J'ai moi-même recherché des discussions décentes sur le CRTP. Todd Veldhuizen's Techniques for Scientific C++ est une excellente ressource pour cela (1.3) et de nombreuses autres techniques avancées comme les modèles d'expression.

En outre, j'ai trouvé que vous pouviez lire la plupart des articles originaux de Coplien C++ Gems sur Google Books. C'est peut-être toujours le cas.

18
fizzer

J'ai dû chercher CRTP . Après avoir fait cela, cependant, j'ai trouvé des informations sur Polymorphisme statique . Je soupçonne que c'est la réponse à votre question.

Il s'avère que ATL utilise ce modèle assez largement.

1
Roger Lipscombe