2017-10-08 3 views
2

J'essaie d'implémenter un mécanisme pour détecter si la classe fournie contient une méthode statique ou non. Il est un code assez simple, mais je ne peux pas comprendre pourquoi decltype() ne fonctionne pas comme prévu pour la spécialisation de EnableIfHasFooMethod classe:SFINAE pour détecter la méthode statique

#include <iostream> 

struct A { 
    static int Foo() { return 0; } 
}; 

template <class T, class = void> 
struct EnableIfHasFooMethod {}; 

template <class T> 
struct EnableIfHasFooMethod<T, decltype(T::Foo)> { 
    typedef void type; 
}; 

template <class T, class = void> 
struct HasFooMethod { 
    static const bool value = false; 
}; 

template <class T> 
struct HasFooMethod<T, typename EnableIfHasFooMethod<T>::type> { 
    static const bool value = true; 
}; 

int main() { 
    std::cout << HasFooMethod<A>::value << std::endl; 
    return 0; 
} 

La sortie est 0, mais devrait être 1.

Répondre

3

Vous oubliez d'ajouter void()

template <class T> 
struct EnableIfHasFooMethod<T, decltype(T::Foo, void())> { /* ... */ }; 
// ...........................................^^^^^^^^ 

Vous devez faire correspondre le deuxième type (void) dans

// ........................vvvv 
template <class T, class = void> 
struct EnableIfHasFooMethod {}; 

afin que votre decltype() doit retourner void ssi (si et seulement si) il y a un Foo() membre dans T.

Vous ne pouvez pas écrire

decltype(T::Foo) 

parce que, dans ce cas, decltype() renvoyer le type de l'organe Foo (le cas échéant) qui ne peut pas être void.

Vous ne pouvez pas écrire

decltype(void()) 

parce que, dans ce cas, decltype() retour jamaisvoid, mais vous voulez ssi il est membre Foo dans T

La solution est donc

decltype(T::Foo , void()) 

donc SFINAE peut fonctionner, à défaut de la substitution sur, s'il n'y a pas un Foo membre et retournant void s'il y a Foo.

+0

J'ai oublié que la spécialisation devrait être pour les paramètres de modèle par défaut. Je vous remercie! – eXXXXXXXXXXX2

+0

aime juste l'opérateur de virgule – quetzalcoatl

+0

@quetzalcoatl - moi aussi. – max66