Modèle de fonction de spécialisation pour les types de référence

Pourquoi la sortie de ce code :

#include  template void f(T param) { std::cout << "General" << std::endl ; } template void f(int& param) { std::cout << "int&" << std::endl ; } int main() { float x ; f (x) ; int y ; f (y) ; int& z = y ; f (z) ; } 

est

Général
Général
Général

Le troisième est surprenant car la fonction était spécialisée pour int&

Edit: Je sais que la surcharge pourrait être une solution appropriée. Je veux juste apprendre la logique derrière tout ça.

Le type de l’expression y et de l’expression z est int . Une référence apparaissant dans une expression ne conservera pas le type de référence. Au lieu de cela, le type de l’expression sera le type référencé, l’expression étant une lvalue.

Donc, dans les deux cas, T est déduit de int et la spécialisation explicite n’est donc pas utilisée du tout.

Ce qui est important à noter (à part le fait que vous devriez vraiment utiliser la surcharge, comme l’a dit un autre gars), c’est que vous avez un paramètre de fonction non référencé dans votre modèle. Avant toute déduction de T rapport au type d’argument, celui-ci sera converti de tableau en pointeur vers son premier élément (pour les fonctions, les arguments seront convertis en pointeurs de fonction). Ainsi, un modèle de fonction avec un paramètre de fonction non référencé ne permet de toute façon pas une déduction précise.

Une référence est juste un alias, pas un type. Ainsi, lorsque vous appelez f (z), il correspond à la première version avec T = int, ce qui est une meilleure option que T = int &. Si vous changez T en T &, alors int et arguments appelleront la deuxième version.

Je sais que ce n’est pas une réponse, mais, à mon humble avis, vous pouvez essayer cela, avec un trait comme une approche dans une structure:

 template struct value_traits { static void print(){std::cout << "General" << std::endl ;} }; template<> struct value_traits { static void print(){std::cout << "const long" << std::endl ;} }; template<> struct value_traits > { static void print(){std::cout << "std::vector" << std::endl ; } }; template<> struct value_traits { static void print(){std::cout << "const int" << std::endl ;} };