web-dev-qa-db-fra.com

Tableau de fonctionnement surcharge

Quelqu'un peut-il résumer l'idée de surcharge de template de fonction? Quelles sont les problèmes, paramètre de modèle ou paramètre de fonction? Qu'en est-il de la valeur de retour?

Par exemple, donné un modèle de fonction

template<typename X, typename Y> void func(X x, Y y) {}

quel est le modèle de fonction surchargé?

1) template<typename X> void func(X x, int y) {}
2) template<typename X, typename Y> X func(X x, Y y) {}
3) template<class X, class Y, class Z> void func(X x, Y y, Z z) {}
26
skydoor

Il y a deux choses distinctes ici: la surcharge des modèles de fonctionnement et de la fonction. Toute deux déclarations de modèles distinctes sont susceptibles d'être des surcharges de l'autre, de sorte que votre question n'a donc pas de sens comme indiqué. (Les trois "surcharges" que vous donnez ne construisent pas sur le premier modèle, mais vous avez plutôt quatre surcharges sur le même nom de la fonction.) Le problème réel est, compte tenu des surcharges et un appel, comment appeler la surcharge souhaitée?

Premièrement, le type de retour ne participe pas au processus de surcharge, qu'il s'agisse ou non d'un modèle impliqué. Donc # 2 ne jouera jamais bien avec # 1.

Deuxièmement, les règles de la résolution de la surcharge de modèles de fonction sont différentes des règles de spécialisation des modèles de classe les plus couramment utilisées. Les deux résolvent essentiellement le même problème, mais

  • les règles relatives aux modèles de classe sont plus simples et plus puissantes, permettant ainsi des fonctions de récursivité et (membre) qui ne diffèrent que par type de retour
  • les règles des modèles de fonctions permettent au compilateur de figurer les arguments de modèle à partir des types d'arguments de fonction

Vous pourriez être capable de résoudre votre problème particulier avec des surcharges de modèles de fonction, mais vous pouvez avoir du mal à résoudre tout bogue qui se pose car les règles sont plus longues et moins de personnes connaissent bien leurs subricacies. J'étais ignoré après quelques années de modèle pirail que la surcharge de modèles de fonction subtiles était même possible. Dans les bibliothèques telles que Boost et STL de GCC, une approche alternative est omniprésente. Utilisez une classe d'emballage modélisée:

template< typename X, typename Y >
struct functor {
    void operator()( X x, Y y );
};
template< typename X > // partial specialization: 
struct functor< X, int > { // alternative to overloading for classes
    void operator()( X x, int y );
};

Maintenant, vous sacrifiez la syntaxe d'instanciation implicite (sans crochets d'angle). Si vous voulez récupérer ça, vous avez besoin d'une autre fonction

template< typename X, typename Y > void func( X x, Y y ) {
    return functor< X, Y >()( x, y );
}

Je serais intéressé d'apprendre à savoir si la surcharge de la fonction peut faire n'importe quoi (en plus de déduction) que la spécialisation de la classe [partielle] ne peut pas ...

Et puis, bien sûr, votre surcharge n ° 3 ne fera jamais face à l'ambiguïté car elle a un nombre différent d'arguments que toute autre surcharge.

3
Potatoswatter

Outre des commentaires, d'autres informations sur le sujet dans l'article de Herb Souteurs pourquoi ne pas spécialiser les modèles de fonctions . J'espère que ce serait utile aussi.

1
Alexander Poluektov