voila, je me suis correctement cassé la tête sur le sujet de la détection de type. En effet, lorsque l'on pratique la métaprogramation, le typage de certains éléments nous est inconnus.
Un bout de code vaut mieux qu'on long discours :
On notera que a et b ne sont pas forcement du même type et que a+b peut être de n'importe quel type en fonction de la surcharge de l'opérateur +.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 template<class A, class B> type? doSomething(A a, B b){ return a+b; }
Nous allons donc utiliser quelque chose de bien peu catholique : typeof. Il faut noter ici que typeof est une extension qui n'est pas supportée par tout les compilateurs. Elle fonctionne notamment avec gcc et Xl (compilo d'IBM).
Comment typeof prend en paramètre une expression quelconque et se substitue a son type. On pourrait donc réécrire notre code comme suit :
mais cela suppose que A et B aient des constructeur par défaut, ce qui n'est pas forcement le cas. Il nou faut donc chercher a contourner cette contrainte. Nous allons chercher a obtenir un objet d'un type de notre choix sans avoir à l'instancier.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 template<class A, class B> __typeof__(A()+B()) doSomething(A a, B b){ return a+b; }
Attention les enfant, n'essayer jamais d'utiliser la suite autrement que pour la détection automatique de type, il peut en résulter de graves failles de sécurité dans votre programme, ainsi que mener a des plantages.
Nous allons tout d'abord faire une classe qui permet de récupérer notre objet de type quelconque sans l'instancier. pour cale, nous allons faire des manœuvres d'un gout douteux avec des pointeurs.
Bien sur, il est exclu d'utiliser tout ca pour autre chose que la détection de type !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 template<class T> class falsePtr{ falsePtr(){} T*e; T& operator*(){ return *e; } T& operator[](int i){ return e[i] } const T& operator*() const { return *e; } const T& operator[](int i) const { return e[i] } }; //Et une belle fonction pour récupérer notre objet : template<class T> T& getObj(){ return *(falsePtr<T>()); }
Voila ce qu'on obtient si l'on reprend notre exemple ci-dessus :
Et voila le travail. C'est pas exactement ce que j'appelle du code propre, mais ca a le mérite de très bien fonctionner. En espérant que ça en aide certains
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 template<class A, class B> __typeof__(getObj<A>()+getObj<B>()) doSomething(A a, B b){ return a+b; }
ATTENTION : Ne générez pas de recherche de type circulaire sans quoi vous obtiendrez des erreurs interne du compilateur pour gcc, ce qui est gênant et pas facile a débugguer
Voici en images ce qu'il ne faudrait pas faire :
Voila, vous savez faire du typage automatique en C++
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 template<class A, class B> __typeof__(doSometing(getObj<A>(),getObj<B>())) operator+(A a, B b){ return a+b; }!
Partager