Quels sont les guides de déduction des modèles et quand les utiliser?

La norme C ++ 17 introduit des “guides de déduction de modèles”. Je suppose qu’ils ont quelque chose à voir avec la nouvelle déduction d’argument de modèle pour les constructeurs introduite dans cette version du standard, mais je n’ai pas encore vu d’explication simple, de style FAQ, sur ce qu’ils sont et ce qu’ils sont pour.

Les guides de déduction de modèle sont des modèles associés à une classe de modèle qui indique au compilateur comment convertir un ensemble de parameters (et leurs types) en arguments de modèle.

L’exemple le plus simple est celui de std::vector et de son constructeur qui prend une paire d’iterators.

 template void func(Iterator first, Iterator last) { vector v(first, last); } 

Le compilateur doit déterminer quel sera le type T vector . Nous soaps quelle est la réponse; T devrait être le nom de typename std::iterator_traits::value_type . Mais comment dire au compilateur sans avoir à taper le vector::value_type> ?

Vous utilisez un guide de déduction:

 template vector(Iterator b, Iterator e) -> vector::value_type>; 

Cela indique au compilateur que, lorsque vous appelez un constructeur de vector correspondant à ce modèle, il déduira la spécialisation vector utilisant le code à droite de -> .

Vous avez besoin de guides lorsque la déduction du type des arguments n’est pas basée sur le type de l’un de ces arguments. L’initialisation d’un vector partir d’une liste initializer_list utilise explicitement le T du vector , il n’a donc pas besoin de guide.

Le côté gauche ne spécifie pas nécessairement un constructeur. La manière dont cela fonctionne est que, si vous utilisez la déduction de constructeur de modèle sur un type, elle correspond aux arguments que vous transmettez à tous les guides de déduction (les constructeurs réels du modèle principal fournissent des guides implicites). S’il existe une correspondance, elle l’utilise pour déterminer les arguments de modèle à fournir au type.

Mais une fois cette déduction effectuée, une fois que le compilateur calcule les parameters du modèle pour le type, l’initialisation de l’object de ce type se déroule comme si rien ne s’était passé. C’est-à-dire que le guide de déduction sélectionné ne doit pas nécessairement correspondre au constructeur sélectionné.

Cela signifie également que vous pouvez utiliser des guides avec des agrégats et une initialisation globale:

 template struct Thingy { T t; }; Thingy(const char *) -> Thingy; Thingy thing{"A Ssortingng"}; //thing.t is a `std::ssortingng`. 

Les guides de déduction ne sont donc utilisés que pour déterminer le type en cours d’initialisation. Le processus d’initialisation proprement dit fonctionne exactement comme avant, une fois cette détermination effectuée.

Voici un cas d’utilisation du guide de déduction que j’ai utilisé pour simplifier la construction de l’object proxy dans un modèle de proxy. J’espère que cela peut vous donner quelques idées Les choses les plus simples que nous pouvons faire des modèles de proxy en utilisant le c ++ moderne Les guides de déduction que j’ai utilisés sont:

 ProxyContainer(vector&) -> ProxyContainer<, ssortingng>; ProxyContainer(int*) -> ProxyContainer<, int>;