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

 C++ Discussion :

Foncteurs et structures de données : partage des responsabilités.


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut Foncteurs et structures de données : partage des responsabilités.
    Salut à toutes et à tous !

    Me revoilà à gratouiller des conseils

    J'ai un type de données D à deux dimensions (spatial/temporel). Pour des raisons pratiques, il me paraissait mieux d'implémenter ça sous forme de vecteurs de vecteurs et non de matrices (j'ai essayé, c'était le bazar, j'ai fait demi-tour ).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    class D
    {
        public:
            D();
            D(const std::string & name, const std::vector<std::vector<double> >& data);
            virtual ~D();
     
            // Read-Only Iteration along first dimension
            typedef std::vector<std::vector<double> >::const_iterator const_iterator;
            const_iterator begin() { return m_data.begin(); }
            const_iterator end() { return m_data.end(); }
     
        protected:
        private:
            std::string m_variableName;
            std::vector<std::vector<double> > m_data; 
            int m_spatialLength;
            int m_temporalLength;
    };
    Maintenant, j'aimerais appliquer un foncteur à chaque double contenu dans le champs m_data. Bon, y'a du foreach de foreach dans l'air, ça ça devrait aller.
    Mais j'ai du mal à intuiter (et googliser) sur qui doit faire quoi.

    Est-ce que c'est le foncteur qui décortique la donnée D avec des foreach pour finalement s'appliquer sur chacun des doubles, ou est-ce que c'est la donnée qui accueille un pointeur sur le foncteur pour descendre les dimensions et l'appliquer sur chaque double ?

    Infos:
    - m_data est assez gros, normalement constant, on a accès à D via un shared_ptr. Je ne sais pas trop quand le déférencer (ni même si je dois le faire).
    - le foncteur est une composition utilisable via un unique_ptr

    Merci d'avance de votre aide !

  2. #2
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 6
    Par défaut
    Eh bien déjà, il y a un problème de constitude. Si tu donnes un const_iterator, il n'est pas possible de modifier ce sur quoi il itère. Donc il faudrait que tu aies une fonction map interne à la classe qui prenne en argument le foncteur pour l'appliquer; pour ma part je trouve ça un peu moche, mais c'est à toi de voir.

    Si tu décides de donner l'accès à l'extérieur ou que tu le fais de l'intérieur, ce n'est pas nécessaire de s'embarrasser avec foreach:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (auto& v : m_data)
      for (auto& d : v) 
        mon_foncteur(d); // d = mon_foncteur(d) selon la sémantique de ton foncteur

    Les changements sont minimes en ajoutant la sémantique des pointeurs:

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (auto& v : *monD)
      for (auto& d : v)
        (*mon_foncteur)(d);

    donc je vais essayé avec une switch

  3. #3
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Merci de ta réponse, j'y vois plus clair !
    Donc il faut obligatoirement modifier la collection sur laquelle on itère (ça veut dire qu'il faudra bien que je fasse un jour ou l'autre une copie de cette donnée partagée...).
    Je pensais reconstruire une autre collection à côté au fur et à mesure des itérations. C'est peut-être à la fois très moche est pas efficace du tout ?

  4. #4
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    Sur l'efficacité, c'est sûr qu'une modification sur place est moins "chère" qu'une copie. Mais une copie est tout à fait une possibilité. Dans ce cas-là, tu peux utiliser std::transform :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    template <typename Foncteur>
    std::vector<std::vector<double>> fmap_helper(const shared_ptr<D> old_d, Foncteur& fn) {
      std::vector<std::vector<double>> new_vec(old_d->end() - old_d->begin()); // à tout prendre faisons l'allocation mémoire d'un coup
      for (const auto& v : *old_d) {
        std::vector<double> ds(v.end()-v.begin()); // idem
        std::transform( v.begin(), v.end(), std::back_inserter(ds), fn);
        new_vec.emplace_back(std::move(ds)); // emplace_back et move semantics
      }
      return new_vec; // RVO optimisation
    }
     
    template <class Foncteur>
    std::shared_ptr<D> fmap(const shared_ptr<D> old_d, std::string nouveau_nom, Foncteur& fn)
      return std::make_shared<D>(nouveau_nom, fmap_helper(old_d, fn));
    }

  5. #5
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Glups

    On va prendre la modification sur place

    Mais merci beaucoup pour ta réponse !!!!

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 158
    Billets dans le blog
    4
    Par défaut
    Quitte à vouloir un truc performant, commence par ne pas utiliser de vector de vector.
    Quand tu auras un truc fonctionnel, on verra pour la performance.
    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.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Quelle structure de données ? Analyse des occurrences d'un trigramme
    Par Tidus159 dans le forum Algorithmes et structures de données
    Réponses: 46
    Dernier message: 12/04/2009, 20h35
  2. VmWare sous XP: partager des données avec Linux
    Par EvilAngel dans le forum VMware
    Réponses: 18
    Dernier message: 06/01/2009, 14h03
  3. Réponses: 9
    Dernier message: 15/12/2006, 12h29
  4. Réponses: 3
    Dernier message: 11/12/2006, 13h18

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