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 :

Désactiver une portion de code


Sujet :

C++

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut Désactiver une portion de code
    Bonjour à tous,

    D'une manière statique, je définis des données qui seront activées ou non :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template<class T>
    class DataHelper
    {
       enum { activated = false; }
    };
    template<> class DataHelper<Data1> { enum { activated = true }; };
    template<> class DataHelper<Data2> { enum { activated = true }; };
    template<> class DataHelper<Data4> { enum { activated = true }; };
    Puis des opérations sur ces données, pouvant être activées ou non :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template<class T>
    class OPHelper
    {
       enum { activated = false; }
    };
    template<> class OPHelper<OP1> { enum { activated = true }; };
    template<> class OPHelper<OP2> { enum { activated = true }; };
    template<> class OPHelper<OP3> { enum { activated = true }; };
    template<> class OPHelper<OP4> { enum { activated = true }; };
    Chaque OPx a besoin de Datax pour fonctionner. Une opération peut-être activée ou non, mais si elle est activée, il lui faut une cohérence de l'activation de la donnée correspondante.

    Dans ce cas, j'aimerais lancer une erreur de compilation, car OP3 a été activée, mais pas Data3.

    Comment puis-je m'y prendre ? Avec du static_assert ?

    Car je ne peux pas faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static_assert(OPHelper<OP3>::activated && DataHelper<Data3>::activated, "error")
    Etant donné que ce ne serait pas une erreur de désactiver la fonctionnalité..

    Où alors est-ce qu'il y aurait ce genre d'équivalent ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #if OPHelper<OP3>::activated
    static_assert(DataHelper<Data3>::activated, "OP3 activated but not Data3");
    #endif
    Merci pour vos réponses

    A bientôt
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  2. #2
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    Peut-être ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static_assert(!OPHelper<OP3>::activated || (OPHelper<OP3>::activated && DataHelper<Data3>::activated), "error")

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Ce que tu peux faire, c'est te baser sur le fait que tout ce qui n'est pas déclaré "en temps utiles" provoquera une erreur de compilation

    Tu peux donc parfaitement modifier "juste un tout petit peu" ton code sous une forme proche de
    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
    struct Data1{};
    struct Data2{};
    struct Data3{};
    template<class T>
    class DataHelper; // on laisse la classe générique déclarée, mais non définie ;)
    /* par contre, on définit toutes les spécialisations qui nous intéressent :D
     */
    template<> class DataHelper<Data1>
    {
        public:
            enum { activated = true };
    };
    template<> class DataHelper<Data2>
    {
        public:
            enum { activated = true };
    };
     
    template<class T>
    class OPHelper
    {
      /* nous aurons une erreur de compilation au minimum proche de
       * DataHelper<T>::activated undeclared ...." :D
       */
       enum { activated =DataHelper<T>::activated };
    };
    int main()
    {
       OPHelper<Data1> d1; // OK
       OPHelper<Data2> d2; // OK
       OPHelper<Data3> d3; // KO error: incomplete type 'DataHelper<Data3>' used in nested name specifier|
     
    }
    Et, si tu compiles en C++11, tu dois meme pouvoir profiter du static_assert pour obtenir un message un peu sympa
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    Citation Envoyé par Ekleog Voir le message
    Peut-être ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static_assert(!OPHelper<OP3>::activated || (OPHelper<OP3>::activated && DataHelper<Data3>::activated), "error")
    Pfff je me sens un peu.. j'ai besoin de vacances je crois ^^ Merci beaucoup
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  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
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Sinon, il y a le ou exclusif pour ça (ou dans ton cas le non XOR) :
    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
    template<class T>
    struct DataHelper;
    struct Data1{};
    struct Data2{};
    struct Data3{};
    struct Data4{};
     
    template<> struct DataHelper<Data1> { enum { activated = true }; };
    template<> struct DataHelper<Data2> { enum { activated = false }; };
    template<> struct DataHelper<Data3> { enum { activated = true }; };
    template<> struct DataHelper<Data4> { enum { activated = false }; };
     
    template<class T>
    struct OPHelper;
     
    struct OP1{};
    struct OP2{};
    struct OP3{};
    struct OP4{};
    template<> struct OPHelper<OP1> { enum { activated = true }; };
    template<> struct OPHelper<OP2> { enum { activated = true }; };
    template<> struct OPHelper<OP3> { enum { activated = false }; };
    template<> struct OPHelper<OP4> { enum { activated = false }; };
     
    static_assert(!(OPHelper<OP1>::activated ^ DataHelper<Data1>::activated), "error 1");
    static_assert(!(OPHelper<OP2>::activated ^ DataHelper<Data2>::activated), "error 2");
    static_assert(!(OPHelper<OP3>::activated ^ DataHelper<Data3>::activated), "error 3");
    static_assert(!(OPHelper<OP4>::activated ^ DataHelper<Data4>::activated), "error 4");
    ceci dit, j'abonde dans le sens de Koala. Si DataN et OpN sont très fortement liées (car je suppose qu'on n'utilise pas Data[i] avec OP[j] si i!=j), alors il faut probablement lier les trois dans un trait (?) dédié
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template<typename data_, typename op_, bool activated_>
    struct OP_trait
    {
       typedef data type_data;
       typedef op type_op;
       enum {activated = activated_};
    };
     
    OP_trait<OP1,Data1,true>::type_data
     
    OP_trait<OP2,Data2,false>::activated

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    Je vais utiliser ce OU exclusif

    Merci à vous !
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  7. #7
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    Attention, le ou exclusif implique que l'activation d'un Data implique l'activation de l'Op correspondant.

    Mais si tu utilises le ou exclusif (et donc que tu lies fortement Data et OP car chacun nécessite l'autre), mieux vaut alors utiliser le trait unique que propose 3DArchi à la fin de son message.

  8. #8
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    Ha oui.. je vais utiliser la première solution alors.

    Car un Data n'est pas lié à une opération particulière, en revanche, une OP a besoin d'un ou plusieurs Data activée. Et un Data peut être utilisé dans plusieurs OP.
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  9. #9
    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 data n'est pas liée à OP mais que OP est liée à 1 ou + data, tu as quand même à inscrire ce lien dans un trait dédié. Ensuite, tu peux utiliser la MPL pour vérifier que tout va bien :
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    #include <boost\mpl\vector.hpp>
    #include <boost\mpl\accumulate.hpp>
    #include <boost\mpl\bool.hpp>
    #include <boost\mpl\and.hpp>
    #include <boost\mpl\next_prior.hpp>
    #include <boost\mpl\placeholders.hpp>
    #include <boost\mpl\if.hpp>
     
    using boost::mpl::placeholders::_1;
    using boost::mpl::placeholders::_2;
     
    struct Data1{};
    struct Data2{};
    struct Data3{};
    struct Data4{};
     
    struct OP1{};
    struct OP2{};
    struct OP3{};
    struct OP4{};
     
     
    template<class T>
    struct DataHelper;
     
    typedef boost::mpl::bool_<true> DataActivated;
    typedef boost::mpl::bool_<true> DataNotActivated;
     
    template<> struct DataHelper<Data1> : DataActivated {};
    template<> struct DataHelper<Data2> : DataNotActivated {};
    template<> struct DataHelper<Data3> : DataActivated {};
    template<> struct DataHelper<Data4>  : DataNotActivated {};
     
     
     
    template<typename data_, typename op_, bool activated_>
    struct OP_trait
    {
       typedef data_ type_data;
       typedef op_ type_op;
       typedef boost::mpl::bool_<activated_> activated;
    };
     
    template<typename data_>
    struct is_data_activated
    {
        typedef typename DataHelper<data_>::type type;
    };
     
    template<class trait_op>
    struct check_op
    {
    private:
        typedef typename boost::mpl::accumulate<
              typename trait_op::type_data
            , boost::mpl::bool_<true>
            , boost::mpl::and_< is_data_activated<_2>,_1 >
            >::type data_activated_type;
    public:
        typedef typename boost::mpl::if_<
            typename trait_op::activated
            ,data_activated_type
            ,boost::mpl::bool_<true>
        >::type type;
        static const bool value = type::value;
    };
     
    typedef OP_trait<boost::mpl::vector<Data1,Data3>, OP1,true> trait_op1; //op1 liée à Data1 et Data3
    static_assert(check_op<trait_op1>::value,"error op 1");
     
    typedef OP_trait<boost::mpl::vector<Data1,Data2>, OP2,true> trait_op2; //op2 liée à Data1 et Data2
    static_assert(check_op<trait_op2>::value,"error op 2");
     
    typedef OP_trait<boost::mpl::vector<Data3>, OP3,true> trait_op3; //op3 liée à Data3
    static_assert(check_op<trait_op3>::value,"error op 3");
     
    typedef OP_trait<boost::mpl::vector<Data4,Data2>, OP4,false> trait_op4;//op4 liée à Data4 et Data2
    static_assert(check_op<trait_op4>::value,"error op 4");
     
    int main()
    {
        return 0;
    }

Discussions similaires

  1. tester d'une portion de code
    Par Ashen-Shugar dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 19/04/2008, 13h07
  2. Réponses: 3
    Dernier message: 22/01/2008, 08h58
  3. Executer une portion de code uniquement si le javascript est actif
    Par Rakken dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 07/04/2007, 10h23
  4. [java.lang.class] Votre avis sur une portion de code
    Par be_tnt dans le forum Langage
    Réponses: 3
    Dernier message: 18/10/2006, 16h55
  5. gestion d'erreur resume next sur une portion de code
    Par aarlock dans le forum Access
    Réponses: 2
    Dernier message: 02/06/2006, 15h28

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