Pourquoi s'efforcer d'éviter std::enable_if dans les signatures de fonction ?
std::enable_if, un outil polyvalent en C, peut être utilisé de plusieurs manières pour définir conditionnellement des fonctions ou des classes en fonction de critères spécifiés. Cependant, Scott Meyers a mis en garde contre son utilisation dans les signatures de fonctions. Comprendre cette recommandation nécessite une exploration des différentes stratégies disponibles avec std::enable_if et de leurs implications.
Options de mise en œuvre :
<code class="cpp">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; } };</code>
<code class="cpp">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; } };</code>
<code class="cpp">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; } };</code>
Approche préférée :
L'approche la plus favorable consiste à placer le activate_if dans les paramètres du modèle. Cette technique offre des avantages à la fois en termes de clarté et de polyvalence.
Clarté :
La clause activate_if peut être distincte des types de retour et d'argument, ce qui permet d'obtenir un code plus lisible. Même avec l'utilisation de modèles d'alias pour réduire l'encombrement, les clauses fusionnées dans les autres approches combinent toujours des concepts séparés et distincts.
Polyvalence :
Cette technique peut être universellement appliqué à divers contextes, y compris les constructeurs sans types de retour et les opérateurs qui interdisent les arguments supplémentaires. SFINAE, la clé derrière le comportement conditionnel de std::enable_if, s'applique uniquement aux modèles, renforçant ainsi l'universalité de cette approche.
Évitement de std::enable_if dans les types de retour :
Lors de l'utilisation de std::enable_if dans les types de retour, le problème ne vient pas de la signature de la fonction mais plutôt des spécialisations des modèles. Meyers déconseille cette pratique pour des raisons de clarté et de cohérence. La spécification des types de retour avec activate_if introduit une incohérence entre les définitions de modèle et le modèle de base :
<code class="cpp">template<typename T> struct Check4 { typename std::enable_if<std::is_same<T, int>::value, int>::type read() { return 42; } int read() { // error: redeclared without 'typename' return 3.14; // never used } };</code>
Modèles de fonctions membres et non-membres :
Les préoccupations et recommandations discutées s'appliquent aux modèles de fonctions membres et non membres. Il n'y a pas de différences notables dans l'approche.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!