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

SL & STL C++ Discussion :

Je suppose que les templates dynamiques n'existent pas..


Sujet :

SL & STL C++

  1. #1
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut Je suppose que les templates dynamiques n'existent pas..
    Je voudrais faire quelque chose comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <int keysize>
    struct MaClasse
    {
     long s_offset,s_length;
     char s_key[keysize];
    };
     
    void foo(int keysize)
    {
    MaClasse<keysize> *p=new MaClasse<keysize>();
    ...
    }
    Je rêve de pouvoir déclarer des structures dont la taille serait définie au runtime et non à la compilation.

    On peut le gérer soi-même mais c'est un peu casse-gueule:
    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
    struct MaClasse
    {
     long s_offset,s_length;
     //char s_key[...];
    };
     
    void foo(int keysize)
    {
    char *t_ptr=new char[sizeof(MaClasse)+keysize];
    MaClasse *p=new(t_ptr) MaClasse();
    ...
    p->s_offset=0;
    p->s_length=327
    strcpy((char *)(p+1),"abcdef");
    }
    Une aide du langage serait bienvenue.

  2. #2
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Tu supposes bien

    Plus besoin de gérer des tableaux dynamiques manuellement comme il fallait le faire en C.
    En C++, on utilise les conteneurs de la STL, à savoir std::vector, std::list et d'autres. C'est bien plus sympa à utiliser que les tableaux en C, un grand bol d'air !

    EDIT : Et std::string pour les chaines de caractères.
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  3. #3
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Je crois que tu ne m'as pas compris...
    La stl c'est bien quand tout est défini à la compilation.
    Je souhaite aller au-delà.

    Relis bien mon premier morceau de code avec template <int keysize>.

  4. #4
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Ce que tu veux faire n'est pas réalisable : un argument template doit être constant et défini à la compilation.

    J'ai compris que tu voulais un tableau dont la taille est déterminée à l'exécution. Un tel tableau s'appelle un conteneur, ce que la STL implémente.

    C'est bien ça que tu voulais savoir ?
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  5. #5
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Je voudrais définir des "structures" de taille variable et dépourvue de pointeurs (implicites ou explicites). Un conteneur peut contenir plein de pointeurs implicites.
    Pourquoi ? Pour pouvoir fair ceci par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MaClasse<keysize> mc;
    ...
    ReadFile(&mc,sizeof(MaClasse<keysize>));
    ...
    WriteFile(&mc,sizeof(MaClasse<keysize>));
    Un truc comme ceci par exemple est inutile:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::string s;
    ...
    ReadFile(&s,sizeof(std::string));
    ...
    Bref, en attendant une hypothétique extension du langage, comment gérer des flux binaires "extérieurs" ?

  6. #6
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Un argument template doit être connu à la compilation. En gros, le template d'une classe va générer implicitement autant de classes qu'il existe de combinaisons de valeur d'arguments. Ce n'est donc pas un manque du langage, aucune extension dans aucun langage de programmation ne pourra changer cela.

    Pour la gestion des flux, tu trouveras peut-être ton bonheur ici : http://cpp.developpez.com/faq/cpp/?page=SL
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  7. #7
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par camboui Voir le message
    Je voudrais définir des "structures" de taille variable et dépourvue de pointeurs (implicites ou explicites). Un conteneur peut contenir plein de pointeurs implicites.
    Pourquoi ? Pour pouvoir fair ceci par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MaClasse<keysize> mc;
    ...
    ReadFile(&mc,sizeof(MaClasse<keysize>));
    ...
    WriteFile(&mc,sizeof(MaClasse<keysize>));
    Un truc comme ceci par exemple est inutile:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::string s;
    ...
    ReadFile(&s,sizeof(std::string));
    ...
    Bref, en attendant une hypothétique extension du langage, comment gérer des flux binaires "extérieurs" ?
    Vive la sérialisation. Regarde ce que Boost propose, tout est automatique.

  8. #8
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    +1 pour la sérialisation.

    Et tu pourrais même t'en tirer de manière élégante en redéfinissant les opérateurs >> et <<, le tout en fixant si nécessaire la taille à lire à l'appel de l'opérateur.

  9. #9
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    En fait, si les templates dynamiques existaient (ce qui est impossible puisqu'il faut instancier la classe pour chaque valeur possible du paramètre), la sérialisation n'aurait aucun intérêt. Pas plus que les fonctions virtuelles, d'ailleurs.

  10. #10
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Je rêve de pouvoir déclarer des structures dont la taille serait définie au runtime et non à la compilation.
    C++ ne le permet pas. Le modèle de construction d'objet n'est tout simplement pas conçu pour : la mémoire est allouée avec un sizeof statique puis le constructeur est appelé.

    Une méthode pour le permettre serait d'appeler d'abord une fonction qui à partir des arguments fournis au constructeur donne la taille de l'objet, allouer cette quantité de mémoire, puis faire la construction.
    C'est un protocole qui gagnerait à être standardisé, et c'est relativement facile à mettre en place de manière propre.

    Il est relativement évident qu'avoir des objets de taille dynamique permettrait d'écrire du code bien plus optimal en terme d'utilisation mémoire et de localité. Par contre, tu ne peux pas mettre d'objets de taille dynamique dans un tableau, bien évidemment, puisque un tableau par construction nécessite que tous les éléments aient la même taille.

    Par contre, ça n'a rien à voir avec les templates dynamiques. Ce que permettrait les templates dynamiques (ce qui ne serait pas si difficile à implémenter, il suffit de permettre les fonctions membres templates virtuelles, et de générer du code à l'édition de liens), ce serait de la programmation à la Python, puisque les templates sont du duck typing.
    Boost ftw

  11. #11
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Je pense que je me suis mal exprimé. Ce n'est pas tant un template dynamique que je cherche (bien que se serait sympa) mais des structures dont la taille est définie au runtime.
    C'est faisable mais il faut le gérer soit même, c'est à ça que sert le 2ème operator new défini par défaut en C++, celui qui accepte un pointeur comme paramètre. Rien n'empêche de faire ceci par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void *p=operator new(sizeof(MaClasse)+sizeof(unsigned));//allocation de mémoire
    MaClasse *mc=operator new(p) MaClasse;//appel de contructeur
    Par ailleurs il est possible d'utiliser les conteneurs de la stl avec des structures dont la taille serait différente de celle connue par le compilateur. On pourrait pour cela faire une spécialization de la classe allocator me semble-t-il:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class allocator<MaClasse>
    {
    ...
    };
     
    allocator<MaClasse> a;
    ...
    std::vector<MaClasse> v(a);
    Ça me fait penser, la spécialization de std::vector<bool,allocator<unsigned> > n'utilise pas l'allocator<bool> par défaut (du moins l'implémentation de MS, je ne sais pas si c'est standard). C'est d'ailleurs un bel exemple de tripatouillage

  12. #12
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    std::vector<bool> est un extra-terrestre, c'est dû à la norme.

    Je pense qu'avant de trafiquer allocator<>, tu devrais bien maîtriser les concepts de base du C++. C'est même limite déconseillé dans les livres dédiés (Effective STL par exemple).

  13. #13
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Si ton problème de base est bien de pouvoir faire des ReadFile/WriteFile sur l'ensemble de ta structure, il est quand même plus adéquat de passer par la serialisation. Ca t'éviteras d'avoir à gérer d'éventuel problème d'endian par exemple si ton exe tourne sur des environnements différents. Après pour pouvoir rajouter des données 'extra' sur ta classe, alors tu peux surcharger l'opérateur new pour accroître la taille demandée des données extra que tu veux rajouter (en faisant attention à d'éventuels problèmes d'alignement lorsque tu voudra écrire dans cette zone de données).

  14. #14
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    J'ai posté un message en anglais sur Usenet en décrivant un protocole.
    http://groups.google.com/group/comp....fa0db83caa9b90

    Mais bien sûr, je n'ai pas eu de réponse (à chaque fois que je propose un truc intéressant, ça a tendance à être le cas...)

    Par contre c'est un protocole qui ne garantit pas que tous les objets d'un même type auront la même taille, donc tu ne peux pas l'utiliser dans vector sans modifier l'interface de vector.

    Ce protocole pourrait par contre être utilisé pour permettre d'avoir des listes chaînées (std::list) d'objets de taille dynamique (chaque nœud aurait alors une taille dynamique).

    Mais en fait toi, ce que tu voudrais, c'est pouvoir créer des nouveaux types à l'exécution...
    Pas possible. Génère tout simplement tous les types possibles à la compilation et permet de dire duquel il s'agit.
    Boost ftw

  15. #15
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Loufoque, tu me plait car c'est EXACTEMENT ça que je cherche.
    Pourquoi me l'as-tu pas montré plus tôt ?
    compact_string<int N>, N n'étant pas connu à la compilation, mais c'est bien sûr !
    Tu vas plus loin que moi, car tu proposes que compact_string<10> soit du même "type" (je devrais dire "compatible" ou "équivalent") que compact_string<20> par exemple, je n'en demande pas tant. Tu le soulignes d'ailleurs, ça poserait un sérieux problème pour std::vector<>, entre autres.
    Et puis l'allocation dynamique dans le stack, comment n'y a-t-on pas encore pensé ? Aucun mécanisme ne le permet il me semble, il serait utile.

    En fait, je sais bien que les templates dynamiques ne sont pas possibles actuellement en C++ (quand même). Lorsque j'ai ouvert cette discussion c'était plus pour débattre que pour poser une question. Bien qu'il me plarait en pratique de savoir comment vous feriez pour implémenter une telle solution en évitant le "pointeur de trop".
    L'écriture d'une classe allocator<> me semble être une solution, la gestion des itérateurs étant sans doute l'aspect le plus complexe.
    Quelqu'un s'y est lancé ?

  16. #16
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Personne ne s'est lancé dans l'écriture d'un allocator<> ?

  17. #17
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Personne ?
    Voilà le genre de code que j'aimerais éviter (et je ne suis pas le seul, loufoque ? ):
    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
    	template <int _NK>
    	struct FKey
    	{
    		unsigned s_ofs,s_len;
    		unsigned s_key[_NK];
    	};
     
     
    	unsigned u,nk=...;
     
    	switch (nk)
    	{
    	case 1:
    		u=sizeof(FKey<1>);
    	case 2:
    		u=sizeof(FKey<2>);
    	case 3:
    		u=sizeof(FKey<3>);
    	...
    	}

  18. #18
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Avec des typelist, tu empiles tous tes cas dans un type (liste), et tu parcours tant que K!=n, ou que la fin de liste n'a pas été atteinte ?
    Ou alors tu appelles une fonction F<0>(n), définie telle que F<K>(n) appellera F<K+1>(n) tant que n!=K ?

    Illustration rapide (limitée par le niveau max de récursion autorisée (20 avec Sun Forte) ; on peut facilement imaginer des hacks pour accepter n'importe quel nombre < 2^20 ; EDIT: mais attention à l'explosion de l'exécutable)
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #include <iostream>
     
    template <size_t K>
    struct FKey {
        unsigned s_1, s_2;
        unsigned k[K];
    };
     
    template <size_t K> size_t search(size_t n)
    {
        if (n==K) {
            return sizeof(FKey<K>);
        } else {
            return search<K+1>(n);
        }
    }
     
    template <> size_t search<20>(size_t n) {
        std::cerr << "too many!" << std::endl;
        return -1;
    }
     
    int main (int argc, char **argv)
    {
        size_t n=0;
        while (std::cout << "N?" && std::cin >> n)
        {
            if (n==0) {
                std::cout << "N must be non null!" << std::endl;
            } else {
                std::cout << "sizeof(FKey<"<<n<<">)=" << search<1>(n) << std::endl;
            }
        }
    }
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  19. #19
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Est-ce que ceci s'approche de ce que tu veux?

    http://groups.google.com/groups/sear...s.bourguet.org
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  20. #20
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    [strike]Non.
    Ce code est sympa mais il n'est qu'une sorte de std::vector<> simplifié.[/strike]

    Le lien donné par loufoque en page précédante défini très bien mon souhait:
    http://groups.google.com/group/comp....fa0db83caa9b90
    Mais comme ce n'est pas supporté en C++ je cherche une manière de contourner cette lacune.

    J'en suis à réécrire du C (sans ++), et donc je ne peux utiliser les fonctionnalités de la stl (algorithms, conteneurs, etc). Enfin si, mais en "copiant" les sources... Fastidieux.


    EDIT: En fait, oui ! (partiellement)
    Je viens de relire ce code et de fait il y a une allocation unique pour une instance de "base" et un nombre défini au runtime d'instances de "elem".
    Toutes mes excuses pour ma première lecture "simpliste" hier en fin de journée.

    Il n'y a plus qu'à trouver le truc pour utiliser des VLA avec les containers de la stl, comme ceci par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector< VLA<base,elem> > v;
    ou comme ceci (aïe )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    VLA< VLA<base1,elem1> , VLA<base2,elem2> > vla;
    PS: aux admins du forum: La balise "strike" n'est pas supportée ?? (barrer du texte). Il faudrait.

Discussions similaires

  1. Réponses: 8
    Dernier message: 01/02/2013, 15h20
  2. selectionner les numéros qui n'existent pas
    Par Invité dans le forum Requêtes
    Réponses: 2
    Dernier message: 01/11/2011, 22h41
  3. Pourquoi les objets courbés n'existent pas ?
    Par bricechris dans le forum Moteurs 3D
    Réponses: 24
    Dernier message: 09/05/2011, 09h09
  4. Afficher les liens qui n'existent pas
    Par engi dans le forum Langage SQL
    Réponses: 5
    Dernier message: 16/10/2008, 20h37
  5. Réponses: 4
    Dernier message: 23/05/2007, 09h51

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