J'essaie d'obtenir une meilleure compréhension de std::enable_if
en C++ 11 et j'ai essayé d'écrire un exemple minimal: une classe A
avec une fonction membre void foo()
qui a des différences Implémentations basées sur le type T
à partir du modèle de classe.
Le code ci-dessous donne le résultat souhaité, mais je ne comprends pas encore complètement. Pourquoi la version V2
fonctionne-t-elle, mais pas V1
? Pourquoi le type "redondant" U
est-il requis?enable_if: exemple minimal pour la fonction membre vide sans arguments
#include <iostream>
#include <type_traits>
template <typename T>
class A {
public:
A(T x) : a_(x) {}
// Enable this function if T == int
/* V1 */ // template < typename std::enable_if<std::is_same<T,int>::value,int>::type = 0>
/* V2 */ template <typename U=T, typename std::enable_if<std::is_same<U,int>::value,int>::type = 0>
void foo() { std::cout << "\nINT: " << a_ << "\n"; }
// Enable this function if T == double
template <typename U=T, typename std::enable_if<std::is_same<U,double>::value,int>::type = 0>
void foo() { std::cout << "\nDOUBLE: " << a_ << "\n"; }
private:
T a_;
};
int main() {
A<int> aInt(1); aInt.foo();
A<double> aDouble(3.14); aDouble.foo();
return 0;
}
Y at-il une meilleure façon d'obtenir le résultat souhaité, à savoir pour avoir différentes implémentations d'une fonction void foo()
en fonction d'un paramètre de modèle de classe?
Votre exemple n'est pas une utilisation appropriée de 'enable_if'. Une surcharge simple résoudrait votre cas. 'enable_if' est surtout utile sur un paramètre de template * deduced *. –
L'utilisation de 'std :: enable_if' serait appropriée pour séparer les types déduits * en virgule flottante * des types, par exemple, * integral *. Deux types spécifiques comme celui-ci seraient mieux adaptés à * la surcharge *. – WhozCraig
@KerrekSB @WhozCraig Comment pourrais-je surcharger dans ce cas particulier? En utilisant une définition hors-classe 'void A :: foo() {}' et 'void A :: foo() {}'? Mon intention serait que le code final contienne uniquement les versions de la fonction qui sont requises (ie pas de fonction 'A :: foo()' si une telle fonction n'est jamais appelée) –
untergam