[Boost::random] Template comme argument d'une fonction...

Template comme argument d'une fonction... [Boost::random] - C++ - Programmation

Marsh Posté le 30-09-2009 à 12:39:41    

Bonjour à tous,
Je suis confronté au problème suivant.
J'ai défini des types de distributions différents :

Code :
  1. typedef boost::variate_generator<
  2.  boost::mt19937, boost::exponential_distribution<>
  3. > rnd_exponential_t;
  4. typedef boost::variate_generator<
  5.  boost::mt19937, boost::uniform_01<>
  6. > rnd_uniform01_t;


Jusque là, ça marche nickel, je peux générer mes nombres aléatoires :

Code :
  1. rnd_uniform01_t LOLcat(rnd_gen,boost::uniform_01<>());
  2. std::cout << "LOLcat sayz\n";
  3. for(int i = 0; i < 50; i++) {
  4.  std::cout << LOLcat() << std::endl;
  5. }
 

Je souhaiterais construire une fonction qui prendrait en argument un variate generator en général, du style :

Code :
  1. double FonctionTest(boost::variate_generator<Engine,Distribution> VariateGenerator) {
  2. std::cout << VariateGenerator() << std::endl;
  3. }
 

Mais là ça ne fonctionne pas. Normal, je sais pas quoi mettre comme type pour l'argument de FonctionTest.
 [:psywalk]

 

edit : j'ai l'impression de lire que c'est impossible ?
http://forum.hardware.fr/hfr/Progr [...] 7486_1.htm


Message édité par SigH-Max le 30-09-2009 à 12:47:28
Reply

Marsh Posté le 30-09-2009 à 12:39:41   

Reply

Marsh Posté le 30-09-2009 à 13:05:25    

sans trop fouiller, je vois deux possibilités : soit ta fonction peut être rendue template auquel cas, tu laisse le compilo déduire le type de l'argument quand tu l'appelles, et ca devrait être bon, soit tu trouves une interface commune à tes variate_generator pour pouvoir les manipuler.


---------------
last.fm
Reply

Marsh Posté le 30-09-2009 à 13:39:31    

Code :
  1. tempalte<class Engine,class Distribution>
  2. double FonctionTest(boost::variate_generator<Engine,Distribution> VariateGenerator) {
  3. std::cout << VariateGenerator() << std::endl;
  4. }


 
ou est le pb ?

Reply

Marsh Posté le 30-09-2009 à 13:44:17    

Joel F a écrit :

Code :
  1. tempalte<class Engine,class Distribution>
  2. double FonctionTest(boost::variate_generator<Engine,Distribution> VariateGenerator) {
  3. std::cout << VariateGenerator() << std::endl;
  4. }
 

ou est le pb ?


Il me dit que Engine et Distribution sont des unknown identifiers.
Je viens de voir que tu avais modifié le code [:prozac] Attends, je vais voir...

theshockwave a écrit :

sans trop fouiller, je vois deux possibilités : soit ta fonction peut être rendue template auquel cas, tu laisse le compilo déduire le type de l'argument quand tu l'appelles, et ca devrait être bon, soit tu trouves une interface commune à tes variate_generator pour pouvoir les manipuler.


Pour la fonction template, le complilateur me sort que les arguments templates ne sont pas supportés dans une fonction template.
L'interface commune, heu... je vois pas trop.


Message édité par SigH-Max le 30-09-2009 à 13:57:13
Reply

Marsh Posté le 30-09-2009 à 14:00:16    

Hum.. Ca a l'air de marcher. Je vois ça après les cours :o

Reply

Marsh Posté le 30-09-2009 à 18:09:24    

Okay, ça marche bien.
Maintenant, je veux créer une fonction de deux variables.
Tout d'abord, la distribution uniforme dans le main :

Code :
  1. double lambda(0.01);
  2. rnd_exponential_t CheeseBurger( rnd_gen,
  3.  boost::exponential_distribution<>( lambda ));


Et, je modifie donc la fonction template en :

Code :
  1. template<class Engine,class Distribution>
  2. void FonctionTest(boost::variate_generator<Engine,Distribution> VariateGenerator1,
  3.      boost::variate_generator<Engine,Distribution> VariateGenerator2) {
  4. std::cout << VariateGenerator1() << VariateGenerator2() << std::endl;
  5. return;
  6. }


Et là, évidemment, le compilateur me sort que Distribution est ambigü, que ça pourrait être boost::exponential_distribution<> ou boost::uniform_01<>... Pile ce que je voulais éviter.
 [:psywalk]

 

edit : Tiens, j'ai trouvé, fallait juste mettre

Code :
  1. template<class Engine,class Distribution1,class Distribution2>
  2. void FonctionTest(boost::variate_generator<Engine,Distribution1> VariateGenerator1,
  3.      boost::variate_generator<Engine,Distribution2> VariateGenerator2) {
  4. std::cout << VariateGenerator1() << VariateGenerator2() << std::endl;
  5. return;
  6. }
 

:)


Message édité par SigH-Max le 30-09-2009 à 18:13:03
Reply

Marsh Posté le 01-10-2009 à 11:03:20    

si tu veut des types different, faut lui dire :o

Reply

Marsh Posté le 01-10-2009 à 16:30:12    

Lapin ?
..Heu, ouais, je galère un peu là.
Le truc c'est que j'aimerais bien avoir un type générique du style :

Code :
  1. typedef boost::variate_generator<Engine,Distribution> variate_generator_t


avec Engine et Distribution quelconques (ou définis un par un...) Mais j'ai beau chercher, je vois pas comment faire :o

Reply

Marsh Posté le 01-10-2009 à 16:31:56    

je vois pas l'interet. Tu fais une fonction tempalte avec le bon typage des parametres c'ets tout

Reply

Marsh Posté le 01-10-2009 à 17:53:18    

En fait, j'ai défini une classe plutôt qu'une fonction, et j'aimerais bien définir un type pour passer un paramètre en variable privée, un truc comme :

Code :
  1. template<class Engine,class Distribution1,class Distribution2>
  2. class ClasseTest(boost::variate_generator<Engine,Distribution1> VariateGenerator1,
  3.      boost::variate_generator<Engine,Distribution2> VariateGenerator2) {
  4. private:
  5. variate_generator_t m_vg1 = VariateGenerator1;
  6. variate_generator_t m_vg2 = VariateGenerator2;
  7. public:
  8. double GetValue1()
  9. {
  10.      return m_vg1();
  11. };
  12. return;
  13. }
  14. void main()
  15. {
  16.      ClasseTest A(LOLcat,rnd_exponential);
  17.      A.Getvalue1();
  18. }
 

edit : Humm... on m'a proposé une solution plus simple, je vais voir ça...


Message édité par SigH-Max le 01-10-2009 à 18:22:00
Reply

Marsh Posté le 01-10-2009 à 17:53:18   

Reply

Marsh Posté le 01-10-2009 à 21:06:11    

euh lol:
 

Code :
  1. private:
  2. VariateGenerator1 m_vg1;
  3. VariateGenerator2 m_vg2;


 
faudrait voir à revoir ses bases :o

Reply

Marsh Posté le 02-10-2009 à 00:40:30    

Joel F a écrit :

euh lol:
 

Code :
  1. private:
  2. VariateGenerator1 m_vg1;
  3. VariateGenerator2 m_vg2;


 
faudrait voir à revoir ses bases :o


Auto-[:prozac]..Mon cerveau est en bouillie, désolé :o

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed