Spécialisation partielle du paramètre de modèle par défaut

Veuillez m’expliquer pourquoi le code suivant est conforme et fonctionne parfaitement. Je suis très confus.

#include template class Base {}; template class Base  { public: Base() { std::cout<<"it works!!!!!\n"; } }; int main() { Base base; // it prints "it works!!!!!" return 0; } 

Ne devrait-il pas tomber dans la forme généralisée de la classe de base Base?

L’argument par défaut s’applique à la spécialisation – et, en fait, une spécialisation doit accepter (pour ainsi dire) les arguments par défaut du modèle de base. Tenter de spécifier un défaut dans la spécialisation:

 template class Base {}; template // ... 

… est une erreur.

De même, si nous modifions la spécialisation pour que sa spécialisation concerne un type autre que celui fourni par le modèle de base:

 template class Base {}; template class Base  

… alors le gabarit de base sera choisi.

Donc, ce qui se passe est la suivante: d’abord les types pour les arguments de modèle sont choisis. Dans ce cas (aucun type spécifié lors de l’instanciation), les deux types sont basés sur les arguments de modèle par défaut spécifiés dans le modèle de base.

Ensuite (comme une étape fondamentalement séparée), il effectue une résolution analogue de la surcharge sur tous les modèles correspondant à ces types d’arguments. Comme d’habitude pour la résolution de surcharge, un type spécifié explicitement est préférable à un type spécifié implicitement, de sorte que votre spécialisation (qui spécifie explicitement int ) est préférable au modèle de base (qui spécifie implicitement l’ int ).

 template class Base {}; 

Ici, les valeurs / initialisation par défaut pour A et B ont été déclarées respectivement comme int et double.

  template class Base  

Ici, dans les définitions de classe, le premier argument est quelque chose comme une valeur constante (ici int; pourquoi déclarer cela simplement pour rendre les choses complexes? Supprimez le premier argument) et le deuxième argument B est la valeur par défaut ‘double’.

 Base<> base; 

Lorsque vous créez l’object de la classe. Bien que vous ne spécifiiez pas les arguments du modèle, le compilateur prend les valeurs par défaut des arguments (A et B) qui sont «int» et «double» et le code s’exécute sans erreur ni avertissement.
Voir ce qui se passe lorsque vous créez l’object en tant que:
Base b; ou Base b;

Lorsque vous écrivez Base<> base; le compilateur essaiera de savoir si l’instanciation de la classe Base<> est possible ou non si le code fonctionne correctement. Dans ce cas, cela est possible en raison de l’argument de modèle par défaut de Base, car le compilateur sait si vous écrivez Base<> il doit créer un object Base . ie: à cause de:

 template class Base {}; 

Donc, le code fonctionne bien.