SFINAE pour vérifier hérité des fonctions de membre du
À l'aide de SFINAE, je peut détecter si une classe donnée a une certaine fonction de membre. Mais que faire si je veux tester hérité des fonctions de membre?
Le code suivant ne fonctionne pas dans VC8 et GCC4 (c'est à dire détecte que A
a une fonction membre foo()
, mais pas que B
hérite de la):
#include <iostream>
template<typename T, typename Sig>
struct has_foo {
template <typename U, U> struct type_check;
template <typename V> static char (& chk(type_check<Sig, &V::foo>*))[1];
template <typename > static char (& chk(...))[2];
static bool const value = (sizeof(chk<T>(0)) == 1);
};
struct A {
void foo();
};
struct B : A {};
int main()
{
using namespace std;
cout << boolalpha << has_foo<A, void (A::*)()>::value << endl; //true
cout << boolalpha << has_foo<B, void (B::*)()>::value << endl; //false
}
Alors, est-il un moyen de tester hérité des fonctions de membre?
- Je ne pense pas que ce soit possible en général. Jusqu'à présent, de toutes façons je l'ai vu avoir certains cas où ils ne parviennent pas.
InformationsquelleAutor Georg Fritzsche | 2009-12-27
Vous devez vous connecter pour publier un commentaire.
Prendre un coup d'oeil à ce fil:
http://lists.boost.org/boost-users/2009/01/44538.php
Dérivé du code lié à cette discussion:
Résultat:
is_call_possible<>
à partir d'ici, groups.google.com/group/comp.lang.c++.modéré/msg/... ? Semble intéressant, aura pour tester plus tard.struct Cpp11 final : A {};
parce qu'il essaie d'hériter d'une classe finale. Aucune solution de contournement?joshperry la réponse est très intelligent et élégant, mais (comme il est indiqué ci-dessous le post) qu'il n'a pas vérifier la signature de foo() correctement et ne fonctionne pas avec les fondamentaux de types (type int): il provoque une erreur de compilation.
Je vous propose une technique qui gère les membres hérités correctement et vérifie la signature de la fonction membre. Au lieu de rentrer dans les détails, je vais vous donner deux exampes et de l'espoir que le code parle de lui-même.
Exemple1:
Nous sommes à la recherche d'une membre avec la signature suivante:
T::const_iterator begin() const
Veuillez noter qu'il vérifie bien que la constness de la méthode, et fonctionne avec les types primitifs, ainsi. (Je veux dire
has_const_begin<int>::value
est faux et ne pas provoquer une erreur de compilation.)Exemple 2
Maintenant, nous sommes à la recherche de la signature:
void foo(MyClass&, unsigned)
Veuillez noter que MyClass n'a pas a être par défaut constructible ou pour satisfaire n'importe quel concept particulier. La technique fonctionne avec le modèle de membres.
Je suis avec impatience d'attente des opinions à ce sujet.
true
dans les deux cas, parce quedata->foo(*arg1, 1u)
est une expression valide dans les deux casIci sont certains de l'utilisation des extraits de:
*Le courage pour tous ce sont plus bas
Vérifier membre
x
dans une classe donnée. Pourrait être var, func, de classe, de l'union, ou enum:Vérifier la fonction de membre de
void x()
:Vérifier la variable de membre
x
:Vérifier membre de la classe
x
:Vérifier membre de l'union
x
:Vérifier membre enum
x
:Vérifier pour toute fonction membre
x
indépendamment de la signature:OU
De détails et de base:
Macros (El Diablo!):
CREATE_MEMBER_CHECK:
CREATE_MEMBER_VAR_CHECK:
CREATE_MEMBER_FUNC_SIG_CHECK:
CREATE_MEMBER_CLASS_CHECK:
CREATE_MEMBER_UNION_CHECK:
CREATE_MEMBER_ENUM_CHECK:
CREATE_MEMBER_FUNC_CHECK:
CREATE_MEMBER_CHECKS:
Que toutes les réponses ont l'air trop compliqué pour moi, j'aimerais vous présenter ma propre solution à l'aide de
std::declval
etstd::enable_if
(GCC 4.8.3)REMARQUE: Il n'est pas exact de vérifier pour la signature, mais pour la fonction appelable avec convertible type de retour. (edit: modifié à partir de
is_same
àis_convertible
)Test
Sortie
Mise à JOUR: Mon pions
Code De Test
Sortie