Cette réponse explique le comportement du programme suivant :
template<typename A, typename B = int >
struct FirstWins {
static constexpr int i = 1;
};
template<typename A>
struct FirstWins<A, float/* anything different from int */ > {
static constexpr int i = 2;
};
template<typename A, typename B = int >
struct SecondWins {
static constexpr int i = 1;
};
template<typename A>
struct SecondWins<A, int > {
static constexpr int i = 2;
};
int main()
{
typedef void Whatever_t;
cout << FirstWins < Whatever_t >::i << endl; // prints 1
cout << SecondWins< Whatever_t >::i << endl; // prints 2
return 0;
}
Cependant, je ne trouve pas de référence réelle décrivant explicitement ce comportement et confirmant ainsi la réponse.
Je n'ai pas pu trouver sur cppreference.com une phrase confirmant que les arguments explicites des modèles sont préférés aux arguments par défaut.
Je soupçonne que ce n'est pas vraiment la règle. La règle est que chaque fois qu'il y a une spécialisation partielle du modèle correspondant aux arguments du modèle, cette spécialisation est toujours choisie par rapport à l'instanciation du modèle primaire. Est-ce correct ? (dans ce cas, les docs expliquent d'une manière ou d'une autre cette règle, mais là encore pas de manière explicite).
2 votes
Un paramètre par défaut fournit simplement un type lorsque le code ne le fait pas. Il n'a aucun effet sur la sélection de la spécialisation.
2 votes
Je pense que vous ne savez pas à quoi servent les arguments des modèles par défaut. Dans votre exemple, cela signifie simplement que
FirstWins<X>
se résout enFirstWins<X, int>
. La sélection effective de la définition deFirstWins<X, int>
se produit après la "substitution" deB
pourint
.0 votes
@Holt : bien sûr, mais ma question porte en fait sur les points suivants
SecondWins<X, int>
. Dans ce cas,SecondWins<X, int>
est préféré àSecondWins<X, =int>
.0 votes
@L.Bruce Parce que
SecondWins<A, B=int>
n'est pas différent deSecondWins<A, B>
pour la sélection des modèles, et donc la spécialisationSecondsWins<A, int>
est préféré à celui qui n'est pas spécialisé. L'argument de modèle par défaut n'a pas d'impact sur la résolution.0 votes
@Holt : D'une certaine manière, cela a un impact, je crois. Regardez
FirstWins
. Il s'agit de la non-concordance entre le paramètre par défautB=int
et l'autre explicitefloat
qui conduit à la sélection du premier.B
la prise en compte par défaut de tout ce qui n'est pasfloat
fait la différence.0 votes
@L.Bruce Il a un impact sur ce que les
FirstWins<X>
ySecondWins<X>
s'étend, c'est tout.FirstWins<Whatever_t>
s'étend àFirstWins<Whatever_t, int>
qui ne correspond pas à la spécialisation, c'est pourquoi la version non spécialisée est choisie.