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) {}
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
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.
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.