IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Tableau de types hétérogènes


Sujet :

Langage C++

  1. #1
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut Tableau de types hétérogènes
    Salut,

    Je me demande comment représenter d'une manière efficace un tableau de données de types hétérogènes. Par exemple il y a du texte, des nombres entiers, des nombres décimaux...
    Pour l'instant ma seule solution est de stocker tout en "string" et de faire la conversion dans le type qui convient lorsque je veux utiliser une donnée. L'inconvénient se situe au niveau performance : si j'utilise plusieurs fois la même donnée je me paye autant de conversions coûteuses. Comment puis-je faire pour éviter cela ?

    Merci

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Une solution est de passer par Boost.Any. Pour en comprendre un peu le principe et le fonctionnement, tu peux lire cet article : Mariage de la Programmation Orientée Objet et de la Programmation Générique : Type Erasure, par Alp Mestan, et en particulier le chapitre V. Réécrivons boost::any

  3. #3
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut
    J'ai l'impression que Boost.Any ne résoud pas mon problème dans la mesure où on se paye à chaque fois une conversion (si je ne m'abuse) en appelant any_cast ou lexical_cast. C'est plus beau que ma solution en "string" j'en conviens, mais plus efficace je me demande...

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    C'est pourtant ce qu'il te faut. La solution passe soit par boost::any, soit par boost::variant.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par tnarol Voir le message
    J'ai l'impression que Boost.Any ne résoud pas mon problème dans la mesure où on se paye à chaque fois une conversion (si je ne m'abuse) en appelant any_cast ou lexical_cast. C'est plus beau que ma solution en "string" j'en conviens, mais plus efficace je me demande...
    J'ai peut être mal compris ton problème. Veux tu stocker dans le même tableau des int, des string, des float et des TaClasseAToi ? Ou veux tu stocker dans un même tableau des objets XXX et pouvoir accéder à tous ces objets des fois comme des int, des fois comme des string, des fois comme des float, et des fois comme des TaClasseAToi ?
    En fait, il y a peut être à la base un problème de conception. Quel est l'objectif exactement ?

  6. #6
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Si tu as un nombre fini de types, tu peux faire un boost::variant<T1, ..., TN> et écrire des static_visitors pour effectuer des actions de manières "polymorphiques" dessus. Plus d'info dans la documentation de boost::variant.

  7. #7
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    J'ai peut être mal compris ton problème. Veux tu stocker dans le même tableau des int, des string, des float et des TaClasseAToi ? Ou veux tu stocker dans un même tableau des objets XXX et pouvoir accéder à tous ces objets des fois comme des int, des fois comme des string, des fois comme des float, et des fois comme des TaClasseAToi ?
    En fait, il y a peut être à la base un problème de conception. Quel est l'objectif exactement ?
    Oui c'est ça je veux à la fois garder l'information la plus complète (a priori sous forme string - par exemple je veux ne veux pas que "007" devienne "7") mais également pouvoir accéder à une ou plusieurs conversions de la même info sans avoir à faire la conversion à chaque fois. Pour autant je ne veux évidemement pas systématiquement stocker toutes les conversions possibles.

  8. #8
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut
    Citation Envoyé par Alp Voir le message
    Si tu as un nombre fini de types, tu peux faire un boost::variant<T1, ..., TN> et écrire des static_visitors pour effectuer des actions de manières "polymorphiques" dessus. Plus d'info dans la documentation de boost::variant.
    Tu pourrais expliciter un peu plus s'il te plait ? Vu que boost revient souvent dans les solutions à mes problèmes je suis en train de m'y mettre mais je ne suis pas encore très bien rodé.

    Cela dit, sans avoir été regarder le code des static_visitors je m'attends à ce qu'ils passent aussi par une conversion dépendante de leur spécialisation. N'est-ce pas ?

  9. #9
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par tnarol
    Oui c'est ça je veux à la fois garder l'information la plus complète (a priori sous forme string - par exemple je veux ne veux pas que "007" devienne "7") mais également pouvoir accéder à une ou plusieurs conversions de la même info sans avoir à faire la conversion à chaque fois.
    Tu veux convertir une chaine vers un autre type sans faire aucune opération de conversion.

    Does not compute.

  10. #10
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Tu veux convertir une chaine vers un autre type sans faire aucune opération de conversion.

    Does not compute.
    Je veux bien faire la conversion mais au maximum une seule fois ! Il se trouve que les manipulations que je veux faire sont susceptibles d'interroger plusieurs dixaines de fois la même ligne d'un tableau... d'où l'intérêt de ne pas faire la conversion à chaque fois.

  11. #11
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Citation Envoyé par tnarol Voir le message
    Tu pourrais expliciter un peu plus s'il te plait ? Vu que boost revient souvent dans les solutions à mes problèmes je suis en train de m'y mettre mais je ne suis pas encore très bien rodé.

    Cela dit, sans avoir été regarder le code des static_visitors je m'attends à ce qu'ils passent aussi par une conversion dépendante de leur spécialisation. N'est-ce pas ?
    http://www.boost.org/doc/libs/1_40_0...l/variant.html
    et en particulier :
    http://www.boost.org/doc/libs/1_40_0...tutorial.basic

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Si je comprends bien, tu souhaites avoir un tableau de valeur et les caster à la demande d'un type vers un autre. Mais une fois le cast fait, tu voudrais garder le résultat pour ne pas avoir à le faire à la requête suivante. Un peu comme un objet qui aurait plusieurs facettes mais serait optimisé pour ne 'calculer' une facette qu'une seule fois et pas à chaque demande. Je ne connais pas de conteneur qui fasse celà. Boost.Variant ou Boost.Any sont plus des unions au sens où une variable a à un moment une valeur d'un type alors que tu veux qu'une variable aie plusieurs valeurs de plusieurs types.
    Tu voudrais pouvoir faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    mon_type valeur = 1;
    std::string str1 = get<std::string>(valeur); // une conversion est faite
    // blalabla...
    std::string str2 = get<std::string>(valeur); // la conversion précédente est retournée si valeur n'a pas changé entre temps.

  13. #13
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Salut,
    Si je comprends bien, tu souhaites avoir un tableau de valeur et les caster à la demande d'un type vers un autre. Mais une fois le cast fait, tu voudrais garder le résultat pour ne pas avoir à le faire à la requête suivante. Un peu comme un objet qui aurait plusieurs facettes mais serait optimisé pour ne 'calculer' une facette qu'une seule fois et pas à chaque demande. Je ne connais pas de conteneur qui fasse celà. Boost.Variant ou Boost.Any sont plus des unions au sens où une variable a à un moment une valeur d'un type alors que tu veux qu'une variable aie plusieurs valeurs de plusieurs types.
    Tu voudrais pouvoir faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    mon_type valeur = 1;
    std::string str1 = get<std::string>(valeur); // une conversion est faite
    // blalabla...
    std::string str2 = get<std::string>(valeur); // la conversion précédente est retournée si valeur n'a pas changé entre temps.
    Oui c'est exactement ça, de plus pour l'instant je me limite à un cas où les données du tableau ne peuvent pas être modifiées -> toute conversion faite reste valable indéfiniment.

  14. #14
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Rien n'existe dans ce sens, et ça me paraît limite infaisable. Il faudrait, pour chaque type de destination pour la conversion que tu demandes, un système de mémoization. Tu dois pouvoir bricoler quelque chose mais ça implique d'avoir une espèce de table associative POUR CHAQUE VALEUR que tu stockes, dans laquelle tu as l'index qui correspond à un type de destination de la conversion, et dont la valeur et ... la valeur une fois convertie. Et dans tout ça il faut aussi que tu prévois des fonctions de conversion pour chaque couple de types possible dans ton appli.

    Un seul mot : bon courage.
    Un autre : revois ta conception, sinon tu vas finir par te jeter du haut d'un immeuble.

  15. #15
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Alp Voir le message
    revois ta conception, sinon tu vas finir par te jeter du haut d'un immeuble.
    Intuitivement, je suis aussi de cet avis. D'où vient ce besoin ? Ne serait-ce pas un problème de conception ?

  16. #16
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Intuitivement, je suis aussi de cet avis. D'où vient ce besoin ? Ne serait-ce pas un problème de conception ?
    Je comprends... mon erreur est peut-être de vouloir à tout prix éviter de typer les données que je manipule. Le souci c'est que je dois les utiliser la plupart du temps sous forme numérique pour calculer de nouvelles données, mais en sortie je dois restituer non seulement les données calculées mais aussi les données d'origine (sans aucune transformation - arrondi ou autre...).

  17. #17
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par tnarol Voir le message
    en sortie je dois restituer non seulement les données calculées mais aussi les données d'origine (sans aucune transformation - arrondi ou autre...).
    C'est pour ça que tu veux les conserver dans leur format d'origine pour être sur que la conversion chaîne->nombre->chaîne n'entraîne pas une différence.

  18. #18
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut
    Hello,
    Dans les données stockées, et de ce que j'ai compris, tu ne peux avoir que du texte ou des nombre? Si c'est le cas, en gardant le stockage sous forme de string tu peux te contenter d'essayer d'extraire la valeur numérique avec un isstringstream et de tester le résultat de l'extraction (pour confirmer qu'il s'agit bien d'une valeur numérique et non du texte brut).

Discussions similaires

  1. [1.1] Tableau multi type
    Par fregolo52 dans le forum Framework .NET
    Réponses: 2
    Dernier message: 16/10/2006, 17h06
  2. Fonctions SQL - Tableau et type anyarray
    Par etiennegaloup dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 07/11/2005, 12h25
  3. Trier un tableau de type défini par l'utilisateur
    Par nonaparus dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 24/10/2005, 21h11
  4. Initialisation d'un tableau de type STRUCT
    Par Axiome dans le forum MFC
    Réponses: 4
    Dernier message: 06/09/2005, 10h58
  5. [Debutant]reallocation de memoire d'un tableau de type perso
    Par killerjeff dans le forum Débuter
    Réponses: 3
    Dernier message: 04/08/2004, 17h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo