Scott Meyers a publié contenu et statut de son prochain livre EC++11. Il a écrit qu'un élément du livre pourrait être _"Évitez std::enable_if
dans les signatures de fonctions"_ .
std::enable_if
peut être utilisé comme argument de fonction, comme type de retour ou comme paramètre de modèle de classe ou de modèle de fonction pour retirer conditionnellement des fonctions ou des classes de la résolution des surcharges.
Sur cette question les trois solutions sont présentées.
Comme paramètre de fonction :
template<typename T>
struct Check1
{
template<typename U = T>
U read(typename std::enable_if<
std::is_same<U, int>::value >::type* = 0) { return 42; }
template<typename U = T>
U read(typename std::enable_if<
std::is_same<U, double>::value >::type* = 0) { return 3.14; }
};
Comme paramètre de modèle :
template<typename T>
struct Check2
{
template<typename U = T, typename std::enable_if<
std::is_same<U, int>::value, int>::type = 0>
U read() { return 42; }
template<typename U = T, typename std::enable_if<
std::is_same<U, double>::value, int>::type = 0>
U read() { return 3.14; }
};
Comme type de retour :
template<typename T>
struct Check3
{
template<typename U = T>
typename std::enable_if<std::is_same<U, int>::value, U>::type read() {
return 42;
}
template<typename U = T>
typename std::enable_if<std::is_same<U, double>::value, U>::type read() {
return 3.14;
}
};
- Quelle solution faut-il privilégier et pourquoi faut-il éviter les autres ?
- Dans quels cas _"Évitez
std::enable_if
dans les signatures de fonctions"_ concerne l'utilisation comme type de retour (qui ne fait pas partie de la signature normale de la fonction mais des spécialisations du modèle) ? - Y a-t-il des différences entre les modèles de fonctions pour les membres et les non-membres ?
0 votes
Parce que la surcharge est tout aussi agréable, généralement. Dans tous les cas, déléguez à une implémentation qui utilise des modèles de classe (spécialisés).
0 votes
Les fonctions membres se distinguent par le fait que le jeu de surcharges comprend les surcharges déclarées. après la surcharge de courant. Ceci est particulièrement important lorsque l'on utilise un type de retour différé variadique (où le type de retour doit être déduit d'une autre surcharge).
1 votes
Eh bien, de manière purement subjective, je dois dire que, bien qu'il soit souvent très utile, je n'aime pas
std::enable_if
pour encombrer mes signatures de fonctions (en particulier l'affreux ajout denullptr
version de l'argument de la fonction) parce qu'il ressemble toujours à ce qu'il est, un hack étrange (pour quelque chose qu'unstatic if
pourrait faire beaucoup plus beau et propre) en utilisant la magie noire des modèles pour exploiter une caractéristique intéressante du langage. C'est pourquoi je préfère le tag-dispatching quand c'est possible (bien, vous avez toujours des arguments supplémentaires étranges, mais pas dans l'interface publique et aussi beaucoup moins de laid et cryptique ).2 votes
Je veux demander ce que fait
=0
surtypename std::enable_if<std::is_same<U, int>::value, int>::type = 0
accomplir ? Je n'ai pas trouvé de ressources correctes pour le comprendre. Je connais la première partie avant=0
a un type de membreint
siU
yint
est le même. Merci beaucoup !4 votes
@astroboylrx C'est drôle, j'allais justement mettre un commentaire notant cela. En gros, ce =0 indique que c'est un défaut, non-type paramètre de modèle. On procède de cette façon parce que les paramètres de modèle de type par défaut ne font pas partie de la signature, de sorte que vous ne pouvez pas les surcharger.
1 votes
J'ai upvoted la question car elle contient toutes les façons d'utiliser enable_if ! ( ;