template - types spécifiques - C++ - Programmation
Marsh Posté le 05-05-2010 à 14:13:06
Il y a des moyens pour arriver a ce genre de chose. Je conseille d'utiliser une bibliotheque qui les encapsule, p.e. boost concept check.
Marsh Posté le 05-05-2010 à 14:16:20
ou bien boost::enable_if ca depend si tu veux empecher l'instanciation OU prevenir d'une erreur.
J'avais uploadé un addeduml à boost type_traits avec des truc genre has_operator_xxx, qui peut servir.
Quand je rentre je te montre
Marsh Posté le 05-05-2010 à 16:29:05
Bon comme je me sens d'attaque, vla un truc fait sur le coin de la table.
Etape 1: detecter qu'un type T supporte operator*
En gros, on veut savoir si pour deux instances de T a et b, a*b est correcte.
L'idée est en gros d'essayer de caluler le type de retour de a*b, si on arrive * existe,
sinon non. Or, on veut pouvoir faire ça sans avoir d'erreur de compilation.
L'idée est d'alors d'utiliser le mécanisme de surcharge de fonction pour tomber dans un cas
foireux dans les moments ou * n'existe pas, et discriminer sur cet appel.
Le code:
Code :
|
En gros, on cherche à calculer le sizeof de x*x. Soit x supporte cette operateur
et son type de retour tombe dans template <class T> char check(T const& )
soit non. Si il n'existe pas que ce passe-t-il ? et bien, c'est le * de any (qui est constructible
à partir de n'importe quoi) qui va etre selectionné. Il renvoit un tag qui va faire que l'on
va appeler char (& check(tag))[2];
Le sizeof de tout ça est donc : 1 si check renvoit char et 2 si il renvoit char[2].
On a donc discriminé la chose.
Exemple: http://codepad.org/ia244fNX
Etape 2: Utilisez ça dans une classe template
Maintenant qu'on sait que T a ou pas un operator*, il faut pouvoir utiliser cette information pour discriminer des classes.
On fait juste de la SFINAE avec enable_if.
Code :
|
Si le has_operator_multiplies<T> renvoit vrai pour T, la seconde specialsiation est prise. Sinon, c'ets la premiere.
Soit on ne mets rien pour obtenir une erreur du genre "incomplete type", soit on met sune static_assert.
Exemple: http://codepad.org/PIx3L7LS
Notes
les has_operator_xxx ont été plus ou moins ajouter à Boost.typetraits mais je sais pas si c'ets dans la 1.43.
La stratégie à base de sizeof ce generalise avec une mini-macro, on peut aussi demander l'existence de methode avec une signature donnée ou l'existence de fonction avec un prototype donnée etc...
Marsh Posté le 08-05-2010 à 08:28:39
Super, une fois de plus merci de poster ce genre de chose
Il y a juste un truc que je comprends pas trop:
Code :
|
Ça c'est syntaxe pour la déclaration d'une fonction qui retourne un char[2] ?
Comme ca, c'est plus clair pour moi... (Je comprends bien qu'au final l'objectif est de retourner quelque chose de plus gros qu'un char si l'on tombe sur un "tag" )
Code :
|
Marsh Posté le 08-05-2010 à 14:02:46
ma semi-proposal de ce truc:
http://www.boostpro.com/vault/inde [...] directory=
Marsh Posté le 08-05-2010 à 16:48:50
Hum ok, je vois...
Je vais regarder de plus près boost::function_types. ca a l'air sympathoche ce que l'on peut faire avec.
Marsh Posté le 05-05-2010 à 13:54:40
Salut,
est-ce que c'est possible en c++, de déclarer un template, qui ne pourra être instancié que si le type présente certaines spécificités, par exemple un operateur *?