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 :

Création de variable avec un type variable !


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Création de variable avec un type variable !
    Bonjour à tous,

    Je cherche à écrire une fonction qui prenne en argument le string 'type', qui doit être choisi dans la liste : char, short int, int, float etc... (vous m'avez compris), et qui déclare une variable 'x' du type choisi.
    Simplissime !?
    Et pourtant je n'y arrives absolument pas !


    Enfin ce n'est pas exacte, un truc de ce style peut marcher :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if ( "char".compare(type) == 0) 
    {
     char x; else if ( "short int".compare(type) ==0 )
                      { 
                      short int x; else if (blablabla...
                      }
    }
    Mais je n'insiste pas, vous avez compris : c'est lourd et en plus ça compile très difficilement ( i.e : que si 'x' est déclaré au préalable, quitte à la re-déclarée, parce que sinon la construction conditionnelle ne permet pas à 'x' d'être déclarée à coup sur... ou en tout cas c'est ce que pense le compilateur )


    J'ai cherché partout de l'aide sur le sujet, genre comment déclarer les variables, typer les variables etc etc, mais toutes les aides que je trouve se référent à des trucs bateaux du style "int myfirstvariable" ou autre...


    Si quelqu'un à une solution toute faite à me mettre sous le nez (même un bout de tuto ou un truc qui m'avance), ou alors une petite idée je suis preneur.


    Merci beaucoup d'avance,
    Cordialement,
    Mark.


    PS : ci-dessous l'ersatz de code que j'ai déjà écrit ; J'ai marqué et mis en commentaire le morceau qui est évidemment faux, mais il montre bien ce que je cherches à faire au moins ... vous voyez non ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
      string type;
      string names[] = {"char", "short int", "int", "float", "double"};
     
      printf("Chose type of stack among : char, short int, int, float, double\n");
      getline( cin, type);
     
      for (int i=0; i < 5; i++)
      {
        if ( names[i].compare( type ) == 0 )
    	{
    	  //names[i] s;                                   <-- Le problème est ici    
    	}
      }

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Points : 2 548
    Points
    2 548
    Par défaut
    Ce genre de chose peut être fait a l'aide de l'a métaprogramation. va faire un tour ici : http://loulou.developpez.com/tutoriels/cpp/metaprog/ .

    Cela dit, je ne suis pas convaincu que tu attaques ton problème de manière pertinente.

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    template tout court ?
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  4. #4
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Si tu n'as que des types aussi simples que ça, tu peux utiliser une union.

    Sinon, si t'as besoin de types non POD (genre std::string), tu peux regarder Boost.Variant : http://www.boost.org/doc/libs/1_36_0...l/variant.html

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 378
    Points : 23 673
    Points
    23 673
    Par défaut
    Citation Envoyé par Marcool Voir le message
    Je cherche à écrire une fonction qui prenne en argument le string 'type',
    Comme dit plus haut, c'est le principe du template, mais ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      printf("Chose type of stack among : char, short int, int, float, double\n");
      getline( cin, type);
    C'est ce que je craignais.

    Tu veux faire cela au runtime. Or, ce que tu cherches à faire est une fonction du compilateur ! Tu ne peux donc pas faire appel à ses services après la compilation, une fois le programme lancé, ce qui est normal.

    De là, tu as trois solutions :

    • Tu utilises un langage interprété. Ils proposent pratiquement tous une fonction eval bien pratique (Perl, Shell, et même le BASIC M$ de 1986 :-).
    • Tu écris une seule fois un template pour ta fonction, et ensuite, comme ta liste propose une nombre d'éléments fini, tu fais une seule fois un switch en énumérant ces mêmes éléments
    • Tu regardes du côté du RTTI, mais ça ne résoudra pas tous tes problèmes.

  6. #6
    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
    La solution la plus "simple" pour le PO me semble boost::variant... Mais il faut récupérer boost, ou du moins variant et ses dépendances.

    Mais ce que tu veux faire est en général très mal vu ... Tu peux nous expliquer dans quel cadre tu as besoin d'une telle fonctionnalité pour ton programme ?

  7. #7
    Invité
    Invité(e)
    Par défaut
    Tout d'abord merci à tous pour vos réponses avisées. Pour vous re répondre à présent, dans un désordre total :

    Mais ce que tu veux faire est en général très mal vu ... Tu peux nous expliquer dans quel cadre tu as besoin d'une telle fonctionnalité pour ton programme ?
    Pourquoi est-ce que ce serrait mal vu ?! J'ai du mal à voir ce qui peut te faire réagir comme ça la dedans Alp ? Si vous voulez vraiment savoir, j'étais parti pour faire un proof of concept du buffer overrun classique, genre :

    "Choisissez un type de variable ..."
    'char'
    "Entrez une valeur numérique ..."
    '657352719373947'
    "Voici la variable stockée dans la variable :
    '-543'
    "Buffer overrun détecté !"

    C'est vrai qu'on peut faire ça en déclarant directement une variable et tout et tout, mais je suis un fana d'interactivité, et j'avais envi que le truc soit portable... En fait je me suis surtout monté à la tête le fait de ne pas pouvoir choisir après l'exécution le type de la variable !




    Tu utilises un langage interprété. Ils proposent pratiquement tous une fonction eval bien pratique (Perl, Shell, et même le BASIC M$ de 1986 :-).
    J'étais à peu près persuadé que quelqu'un me trouverait une solution dans un autre langage, c'est vrai que je pourrais, mais je suis têtu et j'ai voulu finir en C++ ce que j'avais commencé en C++! Mais je vais regarder du coup (peut-être pas dans le BASIC quand même, bien que j'en suis persuadé ça doit avoir ses avantages, on se comprend$ :-), merci là encore.



    Tu écris une seule fois un template pour ta fonction, et ensuite, comme ta liste propose une nombre d'éléments fini, tu fais une seule fois un switch en énumérant ces mêmes éléments
    Eh... ça peut vraiment marcher ça ? (oui oui je vais essayer je sais :-) Ah ouai en fait ça marche (je pensais que ça posait des problèmes de substitution dans le template mais en fait non c'est logique et simple!) Je vois maintenant. Ça revient quand même à utiliser la lourdingue construction conditionnelle décrite dans mon premier post (ok le switch rend ça bien plus propre), mais c'est fonctionnel au moins ! Merci beaucoup Davidbrcz et Obsidian !




    Tu regardes du côté du RTTI, mais ça ne résoudra pas tous tes problèmes.
    D'après ce que je lis , le C++ n'est pas sensé comporter de RTTI... ou en tout cas ça sera du bidouillage non?




    La solution la plus "simple" pour le PO me semble boost::variant...
    Eh ouai... j'avoue que je ne comprends pas trop ce que je suis sensé faire avec variant. Mais il se peut que je n'ai pas bien saisi quel est le rôle de cette fonction... Il me semble qu'elle sert à créer une union un peu spéciale, qui accepte de stocker des types non POD... Non? Si c'est le cas, puisque mes types sont tous POD de toute façon si ça marche avec union (pas encore testé...) alors j'ai pas besoin de variant, si?



    Si tu n'as que des types aussi simples que ça, tu peux utiliser une union.
    Ouai je n'ai que des types simples... et oui une union me semble être une bonne idée. Ça ne me permettra pas de me débarrasser du switch après mais au moins j'ai pas besoin de créer un template avant, une simple union suffit.
    Sauf que comme le but est de faire déborder la variable... et qu'une union se voit réserver l'espace du type le plus gros qu'on pourrait lui demander de contenir, je ne la ferai déborder que quand quelque chose de plus gros qu'un double sera saisi... ce qui n'est pas mon but.
    Dommage, l'idée était de loin la plus propre !



    Cela dit, je ne suis pas convaincu que tu attaques ton problème de manière pertinente.
    Eh... la définition de pertinente est quelque chose de vraiment très subjectif, et je t'en prie deadalnix si tu as plus "pertinent" à proposer comme approche je suis preneur.




    Mot de la fin : merci beaucoup à tous d'avoir pris le temps de me répondre. Je pense avoir trouvé comment je vais faire ça (template puis switch)... je posterai peut-être ce que je fais finalement plus tard dans la soirée pour référence.

    Cordialement,
    Mark.

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Points : 2 548
    Points
    2 548
    Par défaut
    Citation Envoyé par Marcool Voir le message
    Eh... la définition de pertinente est quelque chose de vraiment très subjectif, et je t'en prie deadalnix si tu as plus "pertinent" à proposer comme approche je suis preneur.
    La ligne au dessus.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Ok deadalnix...
    sauf que la page que toi même me dit d'aller voir contient la raison qui fait que cette approche n'est pas pour moi :

    Un autre inconvénient est qu'ici tout ce que nous allons écrire devra être connu du compilateur : certaines données que nous allons manipuler ne pourrons assurément pas être entrées par l'utilisateur lors de l'execution.
    ...or je vise l'interactivité justement.

    Si tout devait être su au moment de la compilation je ferais simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <iostream>
    using namespace std
     
    char x
    int main()
    {
    cout << "Entrez une valeur numérique svp." << endl;
    cin >> x;
    cout << "La valeur enregistrée est : " << x << endl;
    return 0;
    }
    et si la valeur entrée est supérieure à 255 (on suppose le char non signé) alors on véra de suite le buffer overrun... mais ce n'est pas ça que je veux faire.

    Merci quand même ; je suis sûr que la métaprogrammation pourra m'être utile à une autre occasion.

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

Discussions similaires

  1. Utilisation de Ctype avec un type variable
    Par Tommy57 dans le forum Windows Forms
    Réponses: 5
    Dernier message: 09/07/2013, 09h41
  2. Acceder à une variable avec une autre variable
    Par kisscoool dans le forum ActionScript 3
    Réponses: 4
    Dernier message: 21/05/2008, 12h52
  3. types variables avec typedef
    Par Haenou dans le forum C
    Réponses: 4
    Dernier message: 16/04/2008, 09h07
  4. cast avec un type variable
    Par Axwell dans le forum C++
    Réponses: 2
    Dernier message: 13/11/2007, 10h06
  5. variable avec un type non défini
    Par gign2585 dans le forum Windows Forms
    Réponses: 4
    Dernier message: 24/05/2007, 18h10

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