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 :

alternative à switch


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    E/C
    Inscrit en
    Février 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : E/C

    Informations forums :
    Inscription : Février 2006
    Messages : 31
    Par défaut alternative à switch
    Bonjour,
    Par curiosité, je m'intéressais au cas du switch, qui ne permet de traiter que des constantes. Comment avoir un switch qui puisse déclencher sur des variables ? Comme application triviale, on peut penser par exemple à un choix utilisateur qui soit personnalisable (entrée clavier ou autre) via un fichier de config, chargé au runtime.

    J'ai commencé à réfléchir à la question, et suis arrivé rapidement à une classe "templatée" sur le type de variable, et qui mémorise dans un vector des pointeurs de fonction. Ca marche bien, sauf que toutes les fonctions d'appel doivent avoir la même signature (et qui de plus est figée à la compilation, sauf à vouloir).

    J'ai cherché un peu sur le www, mais j'ai pas trouvé grand chose sur ce thème. Quelqu'un aurait-il des pointeurs là dessus, ou une opinion personnelle sur la question (voire même une implémentation ?)

    Merci.

  2. #2
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par défaut
    Bonjour,
    Ta demande n'est pas vraiment clair, un switch, une constante, une variable...

    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
     
    int i; // ma variable
    const int j; // ma constante
     
    //switch sur variable
    switch i
    {
    cas 1:
    cas 2:
    }
     
    //switch sur constant ( Inutile )
    switch j
    {
    cas 1:
    cas 2:
    }

  3. #3
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour sebkramm

    Je ne suis pas sur non plus d'avoir bien compris la question donc j'espère ne pas répondre à côté...

    A priori, ce que tu souhaites, c'est pouvoir ajouter dynamiquement des "case xxx:" et les fonctions associées ? Dans ce cas, ça pourrait ressembler à un design pattern Chaîne de responsabilité : une liste de module traitent une requête un par un ; le premier qui accepte la requête effectue le traitement adéquate et arrête la propagation de la requêt.

    Si ce n'est pas ce que tu recherches, peux tu préciser ta question ?

  4. #4
    Membre averti
    Profil pro
    E/C
    Inscrit en
    Février 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : E/C

    Informations forums :
    Inscription : Février 2006
    Messages : 31
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Je ne suis pas sur non plus d'avoir bien compris la question donc j'espère ne pas répondre à côté...
    Oups, désolé pour l'imprécision.
    Donc, le "problème" du switch, c'est qu'on ne peut déclencher que sur des constantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    switch( ma_var )
    {
       case 1:
    //                action 1
       break;
       case 2:
    //                action 2
       break;
    }
    Eventuellement, on peut avoir des identifiants à la place, mais il faut qu'ils soient
    • const
    • assimilable à un int (char ou autre)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    const int v1 = 1;
    const int v2 = 2;
    switch( ma_var )
    {
       case v1:
    //                action 1
       break;
       case v2:
    //                action 2
       break;
    }
    Au final, ça change pas grand chose...

    La question que je me pose c'est : quelle est la meilleure approche quand on souhaite déclencher sur des variables pour v1, v2 (donc, sans le const), de plus pour des types quelconques.

    (et évidemment sans une illisible chaine "if/else/if/else/if/else/...)

    Par exemple, si je veux faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    string s;
    ...
    switch( s )
    {
       case "aaa":
    //                 action 1
       break;
     
       case "bbb":
    //                 action 2
       break;
    }
    Voire même:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    TypeQuelconque s,v1,v2; // ayant "==" défini, quand même...
    ...
    switch( s )
    {
       case v1:
    //                 action 1
       break;
     
       case v2:
    //                 action 2
       break;
    }
    Alors j'ai cru voir quelque part (retrouve plus où...) que quelqu'un proposait un DP strategy dans ce cas. Mais d'une part je suis pas très sur de voir en pratique comment on ferait, et d'autre part, ça me semble être un bazooka pour tuer une mouche.

    Je suis arrivé à un truc qui permette de faire ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SWITCH<string> my_sw;
     
    my_sw.Add( "aa", f1 ); // f1, f2: les fonctions à appeler
    my_sw.Add( "bb", f2 ); 
     
    // traitement de la string s:
    my_sw.Process( s );
    La classe (simplifiée, le cas du default est aussi prévu):
    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
     
    template < class A > class SWITCH
    {
            public:
                void Process( A a )
                {
                    for( int i=0; i<v1.size(); i++ )
                        if( a == v1[i] )
                            v2[i]();
                }
     
                void Add( A a,  void(*f)() )
                {
                    v1.push_back( a );
                    v2.push_back( f );
                }
     
            private:
                std::vector<A> v1;
                std::vector< void(*)() > v2;
    }
    Ce qui me gène, c'est que, sauf erreur de ma part, on ne peut pas "passer" la signature des fonctions à appeler au template, donc c'est figé pour tout les types de switch d'une unité de compilation donnée. Sauf à utiliser des tricks de préprocesseurs à coups de #ifdef, peut-être...

    Voyez-vous d'autres approches, avec quels avantages/inconvénients ?

  5. #5
    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 : 33
    Localisation : Suisse

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

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Quid d'une simple map avec un {std,boost}::function du bon type pour gérer l'argument ?
    "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)

  6. #6
    Membre averti
    Profil pro
    E/C
    Inscrit en
    Février 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : E/C

    Informations forums :
    Inscription : Février 2006
    Messages : 31
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Quid d'une simple map avec un {std,boost}::function du bon type pour gérer l'argument ?
    Oui, j'ai pensé à utiliser une map au début, mais comment tu gères le cas du default ? (je l'ai prévu dans ma classe, mais pas mis ici pour pas alourdir)

    Et le boost::function, merci, je connaissais pas, ça à l'air d'être justement ce qui me manque pour wrapper une signature de fonction, je vais essayer ça.

Discussions similaires

  1. alterner les couleurs dans un tableau avec xsl
    Par Eithelgul dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 03/05/2015, 23h29
  2. Réseaux : switch, routeur et wi-fi
    Par SteelBox dans le forum Hardware
    Réponses: 4
    Dernier message: 07/12/2003, 20h25
  3. Switch 1000Mbit
    Par Civodul4 dans le forum Hardware
    Réponses: 8
    Dernier message: 02/12/2003, 13h16
  4. switch
    Par drKzs dans le forum C
    Réponses: 3
    Dernier message: 07/10/2003, 07h59
  5. Réponses: 6
    Dernier message: 26/01/2003, 13h45

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