pointeur sur std::vector<T>

pointeur sur std::vector<T> - C++ - Programmation

Marsh Posté le 06-02-2007 à 18:22:02    

Bonjour,
Je ne trouve pas de solution correcte à mon problème.
J'ai des vector<T> où T peut-etre un double, int, string etc...
Je cherche un moyen de faire un pointeur (un seul) qui puisse pointer sur vector<T> quel que soit T.
Alors je sais bien que chaque type a sa taille propre, mais existe-il une méthode pour le faire? En concervant bien sûr dans le pointeur les propriétés du vector (size, begin, end, etc...)
Merci si vous avez des pistes.
 
Edit question subsidiaire : typeof, ça compile partout??

Message cité 1 fois
Message édité par GrosBocdel le 06-02-2007 à 18:28:58
Reply

Marsh Posté le 06-02-2007 à 18:22:02   

Reply

Marsh Posté le 06-02-2007 à 18:40:26    

bah vector<T> n'a pas de classe mére independante de T, ca me parait mort. Sinon regarde du coté de BOOST::Variant ou ecris un truc genre :
 

Code :
  1. template<class T>
  2. struct ptr_vector
  3. {
  4.   typedef std::vector<T>* type;
  5. };
  6. typedef ptr_vector<double>::type pvd;
  7. pvd p = new vector<double>;


 
sinon typeof c'ets pas ANSI, donc j'evite ...

Reply

Marsh Posté le 06-02-2007 à 18:52:58    

Qu'est ce que ça peut être une tare par moment le typage du c++ grrrrrrrrrrrrrrrrrrrrrrrrrr

Reply

Marsh Posté le 06-02-2007 à 19:21:37    

GrosBocdel a écrit :

Je cherche un moyen de faire un pointeur (un seul) qui puisse pointer sur vector<T> quel que soit T.


Si je comprends bien ta question, ce n'est pas faisable avec le typage que tu utilises.
Tu peux y parvenir en remplaçant T par un boost::any, ce qui donnerait std::vector<boost::any>* vec_ptr;  
Tu peux aussi y parvenir en utilisant std::vector<boost::variant<double,int,string> >* vec_ptr;
 
Les deux solutions ont hélas leurs désagréments.

Citation :

Edit question subsidiaire : typeof, ça compile partout??


Pas de mal de compilateurs fournissent cette extension. Mais quelle utilité ici ?

Reply

Marsh Posté le 06-02-2007 à 20:55:47    

++fab a écrit :


Pas de mal de compilateurs fournissent cette extension. Mais quelle utilité ici ?


 
En fait, j'ai une liste de vecteurs créés à la volée, en fonction de lectures de fichiers. Ces vecteurs sont destinés à être affichés dans une table style excel. Si la lecture ne peut pas être interprétée en double, je le passe en string.  
J'ai créé un indexe, qui me dit : le premier vecteur chargé est de type double, le 2eme string etc (j'ai fait la brute avec un vecteur de strings qui me dit "double" "string" etc...), et du coup, je vais voir dans mon vector<vector<double>*> pvdouble, vector<vector<string>*> pvstring à l'indexe donné... par l'indexe...
Donc si tu veux, je me demandais si un truc du style typeof pouvais me permettre d'accélérer les choses sans passer par une multitude de if testant le type et la position dans mes vecteurs de stockage, et donc de changer ma structure de stockage de données.

Message cité 2 fois
Message édité par GrosBocdel le 06-02-2007 à 20:57:17
Reply

Marsh Posté le 06-02-2007 à 21:24:32    

GrosBocdel a écrit :

En fait, j'ai une liste de vecteurs créés à la volée, en fonction de lectures de fichiers. Ces vecteurs sont destinés à être affichés dans une table style excel. Si la lecture ne peut pas être interprétée en double, je le passe en string.


là, j'opterai pour un boost::variant<double,string>. Tu peux voir ça comme une union contenant un double ou une string.
Lis cette page:
http://www.boost.org/doc/html/variant.html
Est-ce que le dernier exemple utilisant un static_visitor<> ne résolverai pas ton problème ?
 

GrosBocdel a écrit :

J'ai créé un indexe, qui me dit : le premier vecteur chargé est de type double, le 2eme string etc (j'ai fait la brute avec un vecteur de strings qui me dit "double" "string" etc...), et du coup, je vais voir dans mon vector<vector<double>*> pvdouble, vector<vector<string>*> pvstring à l'indexe donné... par l'indexe...


C'est complexe.
 

GrosBocdel a écrit :

Donc si tu veux, je me demandais si un truc du style typeof pouvais me permettre d'accélérer les choses sans passer par une multitude de if testant le type et la position dans mes vecteurs de stockage, et donc de changer ma structure de stockage de données.


directement avec typeof, je ne vois pas ...

Reply

Marsh Posté le 07-02-2007 à 08:48:53    

juste comme ça, j'aimerais bien savoir quel type de traitement générique tu appliques à tes int, float et string ...

Reply

Marsh Posté le 07-02-2007 à 18:58:00    

Taz a écrit :

juste comme ça, j'aimerais bien savoir quel type de traitement générique tu appliques à tes int, float et string ...


 
Pour les variable numériques, on va dire toutes les opérations de base + - * / à faire vecteur sur vecteur. Certainement les fonctions mathématiques élémentaires par la suite (log, exp etc). J'ai donc réellement besoin de garder le typage numérique.
Les strings c'est un peu à part. Certainement pas de traitement à part quelques concaténations. Quand je dois mixer numérique/string je passe par un ostringstream. Pour l'intérêt des strings, tu n'as qu'à imaginer des graphs avec "lundi","mardi" etc placés par des couples int/double.
 
Ouep donc pas de traitement générique dit-il.  :)  
J'essaie juste de trouver une bonne structure de données qui fera que je n'aurai pas besoin d'en changer dans 6 mois quand d'autres besoins se présenteront.

Reply

Marsh Posté le 07-02-2007 à 21:20:23    

ben un template et c'est tout :o

Reply

Marsh Posté le 08-02-2007 à 21:09:57    

Taz a écrit :

ben un template et c'est tout :o


 
Template template [:dao]
Et il va savoir comment le template que les vector<double>* il va falloir les chercher dans pvdouble, les vector<string>* dans pvstring, que si c'est pour afficher dans le tableau, faut renvoyer tout ça en string avec un formatage , que si c'est pour dessiner, faut renvoyer tout ça en double...

Reply

Marsh Posté le 08-02-2007 à 21:09:57   

Reply

Marsh Posté le 09-02-2007 à 08:34:48    

bah template

Reply

Marsh Posté le 09-02-2007 à 11:24:01    

Rencarde toi sur les foncteurs, les stratégies et les tuples ;)


Message édité par Joel F le 09-02-2007 à 11:24:17
Reply

Marsh Posté le 09-02-2007 à 22:37:21    

GrosBocdel a écrit :

En fait, j'ai une liste de vecteurs créés à la volée, en fonction de lectures de fichiers. Ces vecteurs sont destinés à être affichés dans une table style excel. Si la lecture ne peut pas être interprétée en double, je le passe en string.  
J'ai créé un indexe, qui me dit : le premier vecteur chargé est de type double, le 2eme string etc (j'ai fait la brute avec un vecteur de strings qui me dit "double" "string" etc...), et du coup, je vais voir dans mon vector<vector<double>*> pvdouble, vector<vector<string>*> pvstring à l'indexe donné... par l'indexe...
Donc si tu veux, je me demandais si un truc du style typeof pouvais me permettre d'accélérer les choses sans passer par une multitude de if testant le type et la position dans mes vecteurs de stockage, et donc de changer ma structure de stockage de données.


 
Pourquoi ne pas stocker que des vector<string> et tester plus tard, quand tu en as vraiment besoin, si les chaînes sont convertibles en double ? En plus cela t'éviterait de présupposer dès la lecture des données qu'un vecteur ne contient que des doubles ou n'en contient aucun. Ou ne stocker que des vector<string> + un tableau de booleens indiquant à côté pour chacun d'eux si les chaînes qu'il contient sont convertibles ? Chsais pas, j'ai l'impression que tu te compliques la tâche, sauf s'il y a un élément de contexte que je ne connais pas.
 

Reply

Marsh Posté le 10-02-2007 à 22:16:33    

J'ai peut-être trouvé une solution à mon problème  

Code :
  1. #include <iostream>
  2. #include <cmath>
  3. #include <vector>
  4. using namespace std;
  5. class mere{
  6. public:
  7. virtual double push(double)=0;
  8. virtual std::string push(std::string)=0;
  9. };
  10. class vdouble : public mere
  11. {
  12. public:
  13. double push(double i) {std::cout<<"push double dans vdouble"<<std::endl;val.push_back(i);return i;}
  14. std::string push(std::string i) {std::cout<<"push string dans vdouble"<<std::endl;val.push_back(NAN);return i;}
  15. private:
  16. std::vector<double> val;
  17. };
  18. class vstring : public mere
  19. {
  20. public:
  21. double push(double i) {std::cout<<"push double dans vstring"<<std::endl;return i;}
  22. std::string push(std::string i) {std::cout<<"push string dans vstring"<<std::endl;val.push_back(i);return i;}
  23. private:
  24. std::vector<std::string> val;
  25. };
  26. int main()
  27. {
  28. std::string chaine="chaine";
  29. vdouble* a=new vdouble;
  30. vstring* b=new vstring;
  31. std::vector<mere*> container;
  32. container.push_back(a);
  33. container.push_back(b);
  34. container[0]->push(3.14);
  35. container[0]->push(chaine);
  36. container[1]->push(chaine);
  37. container[1]->push(3.14);
  38. return(0);
  39. }


 
Est-ce que ça fait bondir quelqu'un?

Reply

Marsh Posté le 11-02-2007 à 01:04:47    

Pourquoi avoir cette séparation ??
Si ton code contenanit un vector de mere* dont l'interface comprenait deux methodes
toString et toDouble, ton code serait bcp plus lisible.
 
Niveau perf ca reste en deça d'un code dirigé par des flags de types ou à base de boost::variant je pense.

Message cité 1 fois
Message édité par Joel F le 11-02-2007 à 01:06:02
Reply

Marsh Posté le 11-02-2007 à 08:04:11    

Joel F a écrit :

Pourquoi avoir cette séparation ??
Si ton code contenanit un vector de mere* dont l'interface comprenait deux methodes
toString et toDouble, ton code serait bcp plus lisible.
 
Niveau perf ca reste en deça d'un code dirigé par des flags de types ou à base de boost::variant je pense.


 
 
Je vais voir si je peux améliorer. Là effectivement, j'ai dû un peu tricher en rajoutant des types non void comme types de retour pour que ça passe.
Faire des vecteurs de boost::variant, j'ai peur que ça ne passe pas avec des routines de math style gsl, qui prennent des double* ou int* pour bosser

Reply

Marsh Posté le 11-02-2007 à 09:52:41    

je ne vois aucun intérêt à ce design vu que les comportement sont exclusif et dépend du type du paramètre et pas du type de l'instance

Reply

Marsh Posté le 11-02-2007 à 10:11:50    

Taz a écrit :

je ne vois aucun intérêt à ce design vu que les comportement sont exclusif et dépend du type du paramètre et pas du type de l'instance


Je n'ai pas compris. En termes un peu moins avancés tu veux dire quoi? Mon niveau n'est pas le même que le tiens, vois tu  :o  J'ai peut-être une grosse poutre dans l'oeil, je ne sais pas
Je veux
1) avoir chacun des types dans les conteneurs adéquats. des double dans des vector<double> des int dans des vector<int> etc... et que ces vecteurs de stockage soient compatibles avec des (int*, taille_vect), des (double*,taille_vect) pour utilisation de bibliothèques mathématiques standard
2) Je veux pouvoir bosser sur les double normalement, et pouvoir les afficher en string si besoin (mais seulement si besoin, c'est à dire si je décide de les afficher dans un tableau style excel, ce qui n'est pas automatique). Dans le cas où je bosse sur des double, je veux toute la vitesse de traitement possible que permettent les vecteurs. Donc pas 50 conversions de type. pvdouble[i]->at(j) renvoie le j eme double du i eme vector
3) Pouvoir accéder à chacun des vecteurs en utilisant un seul nom d'accès. Ici : container. Et donc ne pas passer par if "double" va chercher dans pvdouble, if "string" va chercher dans pvstring.
 
C'est idiot à ce point ce que je cherche à faire?
 
 
edit : ok, désolé Taz, effectivement des types de retour non void ça ne sert à rien. Ca avait foiré pendant que j'étais encore en train de bosser dessus. Donc types de retour void c'est ok.
 


Message édité par GrosBocdel le 11-02-2007 à 11:25:58
Reply

Marsh Posté le 11-02-2007 à 16:29:45    

...

Reply

Marsh Posté le 11-02-2007 à 19:20:19    

pourquoi t'obstines tu a ne pas utiliser boost::variant ou boost:any ?

Reply

Marsh Posté le 12-02-2007 à 06:57:05    

Joel F a écrit :

pourquoi t'obstines tu a ne pas utiliser boost::variant ou boost:any ?


 
Je viens de tester la lecture d'un fichier de données ascii de 50Mo. C'est à peu près la taille des fichiers avec lesquels je travaille.
Lecture avec des types double : 6s
Lecture avec des boost::any : 9s
 
Après la lecture du fichier, il y a éventuellement son traitement, le tracé des données, etc...
Le seul logiciel que je connaisse capable de faire un tracé de 50Mo sans que je m'énerve, c'est gnuplot. Avec une chiée de if un peu partout, mon programme doit le faire actuellement en maxi 2 fois plus de temps que gnuplot.
Si je commence à utiliser des librairies à tout va, je me dirige vers cette bouze qu'est matlab (qui n'a JAMAIS tracé un fichier de 50Mo sans que j'aie le temps d'aller prendre un café pour finallement reset le pc). C'est justement ce que je ne veux pas.
 

Reply

Marsh Posté le 12-02-2007 à 08:58:04    

sauf que boost::variant c'est un peu une bibliothèque template dont le surcout à l'execution est quasi nul :o Il serait de bon [:aloy] de se renseigner avant de dire du käkä [:pingouino]

Reply

Marsh Posté le 12-02-2007 à 19:28:59    

GrosBocdel a écrit :

Je viens de tester la lecture d'un fichier de données ascii de 50Mo. C'est à peu près la taille des fichiers avec lesquels je travaille.
Lecture avec des types double : 6s
Lecture avec des boost::any : 9s


ça c'est prévisible, l'implémentation de any introduit une allocation dynamique. J'avais lu qu'il était possible de l'impémenter sans allocation dynamique pour les types non class je crois, mais je ne sais pas si cette implémentation est utilisée dans les versions récentes de Boost.Any.
 

GrosBocdel a écrit :

[...]
Si je commence à utiliser des librairies à tout va, je me dirige vers cette bouze qu'est matlab (qui n'a JAMAIS tracé un fichier de 50Mo sans que j'aie le temps d'aller prendre un café pour finallement reset le pc). C'est justement ce que je ne veux pas.


Alors là, je ne n'arrive pas à suivre ton raisonnement.


Message édité par ++fab le 12-02-2007 à 19:29:49
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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