Hello,
Connaissez-vous une technique pour n'autoriser l'instanciation d'un template que pour un certain nombre de classes, tout en gardant une définition générique ?
Hello,
Connaissez-vous une technique pour n'autoriser l'instanciation d'un template que pour un certain nombre de classes, tout en gardant une définition générique ?
Bonsoir,
Tu pourrais être plus précis sur ce que tu entends par "un certain nombre de classes" ? Parce que c'est déjà le cas de manière indirect. Si la classe ne propose pas l'interface utilisé dans la définition des membres de ta classe template alors ca va poser des problèmes à la compilation.
Si c'est pour une liste prédéfinie de classe, alors ca doit être possible en jouant avec une type list (ou variadic en C++11) et boost::mpl. Tu codes un algorithme de méta-prog semblable à std::any_of (je crois qu'il n'y est pas dans boost::mpl, mais ca se fait avec un fold), et tu fais hérité ta classe template de std::enable_if</*(*)*/,empty_type> en metant dans (*) le résultat de ton any_of et empty_type un type vide.
Cependant je suis assez sceptique quand à l'intérêt d'un tel système, le contrat implicite imposé par l'utilisation du type dans ta classe template n'ext vraiment pas suffisant ? Si c'est parce que ce contrat est justement implicite, alors les concepts (ceux de boost par exemple) les rendent explictes.
Ma classe template sert à définir l'accès à une table et à ses chamsp, et contient uniquement un enum pour définir les accès sur les champs. Par défaut, tous les champs seront accessibles en lecture seule, et auront donc leur valeur d'enum à 0. Rien dans la définition de ma classe template ne permet d'empêcher une instanciation.
Il va me falloir un peu de temps pour analyser ce bloc de texte.
Sans doute, mais je n'ai pas le droit à Boost...
Il me semble que c'est possible avec Boost.MPL (certainement Boost.Fusion aussi): tu définis à l'interieur de ton template une liste de types authorisés, puis tu fais un static assert (C++11 ou celui de boost) dés les première lignes de ton template (classe ou fonction) en utilisant un des algos de MPL/Fusion pour tester si le type fournis en paramettre est l'un des types donnés.
Bonjour,
à moins qu'il n'entende par là "limiter à X instances", auquel cas j'ajouterais juste une factory par-dessus.
Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
Un peu de programmation réseau ?
Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.
http://www.boost.org/doc/libs/1_36_0...nual/fold.html
C'est celui-ci d'algo.
(Quelque chose comme ca)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 fold<types,false_,or_<equal_to<_2,T> ,_1> >::type
Et pour rendre ca plus lisible, on doit pouvoir faire (à vérifier, j'utilise pas MPL tout les jours) :
Que tu devrais pouvoir ensuite utiliser avec une assertion comme te le propose klaim :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 template<class Sequence, class Value> struct any_of : fold<Sequence,false_,or_<equal_to<_2,Value> ,_1> > { };
Où types est ta liste de type autorisé
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 template<class T> struct A { BOOST_MPL_ASSERT((any_of<types,T>)); };
Si tu n'as pas le droit à boost, alors tu fais pareil en recodant fold _or et equal_to, et en utilisant un autre système d'assertion à la compilation (C++11 par exemple). Pour recoder ces éléments tu peux te baser sur le code de boost::mpl.
PS: A la place de _or on peut aussi utiliser un _if, et à la place d'un fold on peut utiliser un des autres algorithmes d'itération (mpl::accumulate par exemple).
PPS: La solution de l'assertion (pour provoquer l'erreur) proposé par klaim est surment bien mieux que la mienne je pense.
Bon, je crois qu'il va me falloir plonger dans le bouquin d'Abrahams.
Merci à tous !
Partager