Je ne sais pas. Mais j'aurais préférer éviter boost. Et leur code est tellement dispersé, que c'est pas évidant de savoir ce qu'ils font...
Donc c'est pas triviale
Version imprimable
C'est peut-être stupide, mais à quoi serve ces lignes :
Code:
1
2
3 static void Constraints(D* p) { B* pb = p; pb = p; } };
?!?(surtout la première qui fait la même instruction 2 fois ><) ?Code:
1
2
3 IsDerivedFrom() { void(*p)(D*) = Constraints; } };
C'est possible oui... J'ai pas le code sous la main, mais ça se fait.
de toute façon, moi je dis que y'aura bientôt des réponses à toute les questions :mrgreen:
Pour la méthode pour checker si il existe une hiérarchie entre deux types y'a plus simple ... :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 template <typename T, typename U> struct conversion_exists { typedef char yes; struct no { char dummy[2]; }; static T makeT(); // si T n'est pas copy constructible static no tester(...); static yes tester(U); public : enum { exists = sizeof(yes) == sizeof(tester(makeT())) }; enum { existsBothway = exists && conversion<U,T>::exists }; enum { isSame = false }; }; // une spécialisation au cas où les deux types soit les mêmes. // deux spécialisations pour void.
Pour tester un lien de parenté il faudrait plutôt utiliser des pointeurs non ? Parce que là, ça teste toute conversion implicite. Donc entre int et long aussi, par exemple.
Et sinon je crois que tu as une récursion infinie avec existsBothway :mrgreen:
Il faudrait passer un booléen en 3ème paramètre pour décider de faire l'appel ou pas.
Ouai, j'ai fait un peu à l'arrache sur le fofo. Je m'en sert juste pour détecter tout type de conversion. Pour juste tester une hiérarchie c'est trivial avec un ajout de pointeur.
Et non y'a pas de récursion infinie... (dans le deuxiéme cas on appel pas existsBothWay)
Un booléen pour appel de quoi? C'était qu'un toy code hein.
Qu'est-ce qui empêche cet appel ?Citation:
Et non y'a pas de récursion infinie... (dans le deuxiéme cas on appel pas existsBothWay)
C'était éventuellement pour stopper la récursion si nécessaire.Citation:
Un booléen pour appel de quoi?
J'ai pas la norme sous les yeux. Mais t'arrives à me mettre le doute. Mais pour moi existsBothWay et isSame sont jamais instancié avec cet appel, d'où la non récursion. Que ça soit sur VS ou gcc ça passe.
Mieux, si pour tester je remplace
l'appel conversion<U,T>::exists par conversion<U,T>::existsBothWay, le compilo me le refuse. (type incomplet)
Ah oui je viens de saisir. Ca roule alors.Citation:
J'ai pas la norme sous les yeux. Mais t'arrives à me mettre le doute. Mais pour moi existsBothWay et isSame sont jamais instancié avec cet appel, d'où la non récursion. Que ça soit sur VS ou gcc ça passe.
Mieux, si pour tester je remplace
l'appel conversion<U,T>::exists par conversion<U,T>::existsBothWay, le compilo me le refuse. (type incomplet)
Bon ça va... tu m'as quand même fait douter. (pas assez pour que je fouille la norme par contre). Reste que t'avais raison pour les pointeurs. J'ai posté un peu vite.
Mais dans ce cas il faut verifier si U n'est un void*.
EDIT: Désolé ,je n'avais pas vu que le code continuait plus bas.
D'où les commentaires précisant les différentes spécialisation à fournir.
J'y réfléchie t'inquiète ;) Mais je ne suis pas le seul à décider.
Puis je fait cela pour apprendre. SFINAE et moi on viens juste de se rencontrer. J'essaie de comprendre les possibilités.
Je suis pas née avec un ordi et un manuel C++ comme vous. Pour dire, j'ai découvert que la virtualité était héréditaire que depuis 1 mois :whistle2:
Putain de prof et SSII qui nous apprend à faire du C avec du C++ :massacre:
Boost est un peu gros pour ce que je veux faire, mais je vais tous de même en discuter.
Il n'existe pas de lib plus petit qui reprend la partie metaprog? Il me semble avoir vue ça sur le forum mais impossible de retrouver...
Quelle partie metaprog? Parce que c'est un peu vaste...
Ce que t'as du croisé c'est loki non?
Pour l'instant ce qui correspond à mes questions. Il me semble que ca reviens à ce qui est appeler programmation par concept.
La je veux juste savoir si une classe à un membre nommé foo d'un type donné (fonction, int,...). Et ceux quel que soit l'héritage existant.
Je vais regarder merci.
A alors non. Toi tu parles de boost.concept_check. J'en connais pas d'autres. Mais sérieux à coup de SFINAE ça se fait vite fait ce que tu souhaites. (un peu de macro par dessus, quelques workaround, tu secoues, et roulez :p).
@arzar : c'est bien ce que je disais.... c'est vaste :p (des DSEL aux traits, y'a quand même un fossé :p)
Attends qu'on soit claire. Tu veux pouvoir écrire quelque chose comme :
has_fct_foo<bar>::value;
has_member_foo<bar>::value;
has_type_foo<bar>::value; (et par type j'entends typedef, nested class)
ou plus largement :
has_foo<bar>::value
je veut en gros cela
et par exemple qu'avec
has_member_foo<A>::value, has_member_foo<B>::value et has_member_foo<C>::value retournent vrai car j'ai un membre de type uneClass nommé foo. dans l'exemple que j'ai trouvé has_member_foo<B>::value retourne fauxCode:
1
2
3
4
5
6
7
8
9 struct A { uneClass foo; }; struct B : A {}; struct C { uneClass foo; };