Pourquoi la surcharge des modèles et des non-modèles avec la même signature appelle-t-elle la fonction non-modèle?

J’ai ce code:

template void f(T) {} void f(const int &) {} int main() { f(0); } 

Pourquoi appelle-t-il le second au lieu du premier? Je penserais à eux comme étant les mêmes mais ils ne sont clairement pas comme je ne reçois pas d’erreur de redéfinition.

Parce que la deuxième surcharge n’est pas un modèle.

Lorsqu’une fonction de modèle et une fonction non-modèle sont toutes deux viables pour la résolution d’un appel de fonction, la fonction non-modèle est sélectionnée.

Au paragraphe 13.3.3 / 1 de la norme C ++ 11:

[…] Étant donné ces définitions, une fonction viable F1 est définie comme étant une meilleure fonction qu’une autre fonction viable F2 si, pour tous les arguments i, ICSi (F1) n’est pas une séquence de conversion plus mauvaise que ICSi (F2), puis [ …] F1 est une fonction non-template et F2 est une spécialisation de template de fonction […]

L’un est un modèle et l’autre ne l’est pas, ils ne sont certainement pas les mêmes.

La résolution de surcharge est conçue pour préférer un non-modèle à une fonction basée sur un modèle, toutes choses étant égales par ailleurs.