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 :

difficulté avec des templates variadiques (c++0x)


Sujet :

C++

  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut difficulté avec des templates variadiques (c++0x)
    Bonjour, j'ai essayer de créer un GUI et je rencontre quelques problèmes :

    Je souhaite créer une fonction connect (entre un signal et une fonction), qui prend en paramètre un std::string et une classe Callback (qui contient un std::function<void(void*)) .
    Afin de faciliter l'utilisation de cette fonction connect, j'ai créer une fonction
    template<typename R, typename Fc, typename ...Args>
    R make_callback(R& retour, Fc func, Args&...arg).
    Dans l'état actuel, cette fonction est capable de créer un std::function<void(void*)> qui appellera la fonction fc, avec les paramètres qu'il y a dans arg en en stockant la valeur de retour dans retour.

    Voici comment est créée cette fonction :

    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
    template<typename R, typename fc, typename ...Args>
    Callback make_callback(R& retour,fc function, Args&... param)
    {
        std::tuple<Args&...> my_tuple(param...);
        return Callback
        (
            [
                function, &retour,my_tuple
            ]
            (void*even)
                {
                    retour=call_function<R, fc, Args...>(function, my_tuple);
                }
        );
    }
    Avec :

    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
    #ifndef FUNCTION_HPP_INCLUDED
    #define FUNCTION_HPP_INCLUDED
     
     
    #include <tuple>
     
    template<typename R, unsigned int N>
    struct __Apply_aux__
    {
       template<typename Func, typename... ArgsT, typename... Args>
       static R apply(Func f, std::tuple<ArgsT...> & t,Args&... args)
       {
         return __Apply_aux__<R,N-1>::apply(f, t, std::get<N-1>(t), args...);
       }
    };
     
    // Terminal case, call the function with unpacked arguments
    template<typename R>
    struct __Apply_aux__<R,0>
    {
       template<typename Func, typename... ArgsT, typename... Args>
       static R apply(Func f, std::tuple<ArgsT...> &, Args&... args)
       {
         return f(args...);
       }
    };
     
    template<typename R,typename T, typename ...Args>
    R call_function(T fc, const std::tuple<Args&...> & t)
    {
        return __Apply_aux__<R,sizeof...(Args)>::apply(fc, const_cast<std::tuple<Args&...> &>(t));
    }
     
    #endif // FUNCTION_HPP_INCLUDED
    Malheureusement ce code ne permet pas de :

    -ne pas vouloir de valeur de retour
    -d'accéder a ce qu'il y a dans le void*even.

    Pour combler le premier problème, j'ai créé une deuxième fonction (make_callback_void) qui ne prend pas de type de retour. Bien que ce système ne me satisfait pas il est suffisant (si quelqu'un a une autre solution, je prend).

    Pour le deuxième problème, j'ai créé une structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template<typename ...Args>
    class Event
    {
        private :
            std::tuple<Args...> arg;
        public :
            Event(Args...args) : arg(args){}
            std::tuple<Args...> get_tuple(){return arg;}
     
    };
    On indiquera, lors de l'appel de make_callback le type de l'event que la fonction va recevoir (on pourra donc caster le void* en l'event approprié).

    et on créera une deuxième structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<unsigned int N>
    struct my_event_get
    {
    };
    L'objectif :

    Dans le cas ou un des paramètres est un my_event_get<DE_NIMPORTE_QUEl_NOMBRE>, il faudrait pouvoir passer a la fonction ce qu'il y a dans le tuple de l'event.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    double my_function(int one, int two)
    {
           return (double)one/two
    }
     
    struct_servant_a_passer_le_template<int, double/*Ces parametres template permettent d'indiquer le type de l'evenement transmit*/>::make_callback(my_double, my_function, 5, my_event_get<0>);
    Quelqu'un aurait-il une idée comment faire pour que dans la fonction call_function, on puisse faire un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(std::get<N-1>(t)==my_event_get<DE_NIMPORTE_QUEl_NOMBRE>)
    {
            return __Apply_aux__<R,N-1>::apply(f, t,std::get<DU_TEMPLATE DE LA STRUCTURE>(( (std::get<N-1>(t)).get_tuple())), args...);
    }
    Merci d'avance.

  2. #2
    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
    Par défaut
    Salut,
    La piste est probablement d'ajouter une enveloppe sur les arguments qui retourne la valeur au moment de l'appel de la fonction. Pour les arguments non liés à l'évènement, cette enveloppe se contente de retourner ce qui lui a été fourni au moment de la construction du handler. Pour ceux liés à l'évènement, l'enveloppe retourne l'élément associé à l'évènement.
    Je pense que tu devrais fouiller l'implémentation de Boost.Bind. Tu devrais y trouver des idées intéressantes à pêcher pour ton problème.

    Une autre piste est peut être de poser le problème en terme de prog. fonctionnelle. J'ai l'intuition que cette approche pourrait t'aider à mieux poser le problème

    P.S. : pas terrible tous ces passages par référence obligatoire...

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Merci 3dArchi, de m'avoir indiqué la piste de boost::bind, et j'en suis arrivé a une nouveau problème :

    comment écrire une fonction qui fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<typename R, typename Fc, typename ...Args1, typename ...Args2>
    R my_bind(Fc func, std::tuple<Args1...>a1, std::tuple<Args2...>a2)
    {
           return boost::bind(func, a1/*les différents objets de a1 (il faut donc les extraires)*/)(a2/*pareil*/);
    }
    Mon problème se pose pour plusieurs raisons :

    -je ne peux pas faire une fonction du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template<typename ...Args>
    Args.../*L'erreur est ici : il m'est interdit de renvoyer un type variadique*/ extract_tuple(std::tuple<Args...> &t)
    Est-ce du a l'implémentation de mon compilateur ou est-ce dans la norme ?

    Et ce code ci ne marche pas

    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
    template<typename R,unsigned int N, typename ...ArgsF>
    struct get_args_impl_2
    {
        template<typename Fc, typename ...Args, typename ...ArgsFE>
        static R apply(Fc function, ArgsF...argsfait, std::tuple<Args...> E,ArgsFE...finis )
        {
            return get_args_impl_2<R,N-1, ArgsF...>::apply(function, argsfait..., E, std::get<N-1>(E), finis...);
        }
    };
     
    template<typename R,typename ...ArgsF>
    struct get_args_impl_2<R,0,ArgsF...>
    {
        template<typename Fc, typename ...Args, typename ...ArgsFE>
        static R apply(Fc function, ArgsF...argsfait, std::tuple<Args...> E,ArgsFE...finis )
        {
            return boost::bind(function, argsfait...)(finis...);
        }
    };
     
    template<typename R,unsigned int N>
    struct get_args_impl
    {
        template<typename Fc, typename ...Args, typename ...ArgsF, typename ...ArgsE>
        static R apply(Fc function, std::tuple<Args...> t, std::tuple<ArgsE...> E, ArgsF...argsfait)
        {
            return get_args_impl<R,N-1>::apply(function, t, E, std::get<N-1>(t), argsfait...);
        }
    };
     
    template<typename R>
    struct get_args_impl<R,0>
    {
        template<typename Fc, typename ...Args, typename ...ArgsF, typename ...ArgsE>
        static R apply(Fc function, std::tuple<Args...> t, std::tuple<ArgsE...> E, ArgsF...argsfait)
        {
            return get_args_impl_2<R,sizeof...(ArgsE), ArgsF...>::apply(function, argsfait..., E);
        }
    };
     
     
    template<typename R,typename Fc, typename ...Args, typename ...ArgsE>
    R my_bind(Fc function, const std::tuple<Args...>& t, const std::tuple<ArgsE...>& te)
    {
        return get_args_impl<R,sizeof...(Args)>::apply(function, const_cast<std::tuple<Args...>&>(t), const_cast<std::tuple<ArgsE...>&>(te));
    }
    Voici les erreurs :

    error:parameter packs must be at the end of the parameter list|
    error: parameter packs must be at the end of the parameter list|

    Je ne peux donc pas extraire les 2 tuples en même temps. Y a t-il un moyen d'y remédier ? De faire ce que je veux ?

  4. #4
    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
    Par défaut
    Salut
    Citation Envoyé par NoIdea Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<typename R, typename Fc, typename ...Args1, typename ...Args2>
    R my_bind(Fc func, std::tuple<Args1...>a1, std::tuple<Args2...>a2)
    {
           return boost::bind(func, a1/*les différents objets de a1 (il faut donc les extraires)*/)(a2/*pareil*/);
    }
    Normale que ton code mélange construction d'un foncteur et appel de celui-ci ?
    Citation Envoyé par NoIdea Voir le message
    Mon problème se pose pour plusieurs raisons :

    -je ne peux pas faire une fonction du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template<typename ...Args>
    Args.../*L'erreur est ici : il m'est interdit de renvoyer un type variadique*/ extract_tuple(std::tuple<Args...> &t)
    Est-ce du a l'implémentation de mon compilateur ou est-ce dans la norme ?
    Une fonctions ne retourne qu'un seul objet. Là tu veux lui faire retourner une planqué d'objet. Pas possible. Ce n'est même pas une question de template.

    Citation Envoyé par NoIdea Voir le message
    Et ce code ci ne marche pas

    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
    template<typename R,unsigned int N, typename ...ArgsF>
    struct get_args_impl_2
    {
        template<typename Fc, typename ...Args, typename ...ArgsFE>
        static R apply(Fc function, ArgsF...argsfait, std::tuple<Args...> E,ArgsFE...finis )
        {
            return get_args_impl_2<R,N-1, ArgsF...>::apply(function, argsfait..., E, std::get<N-1>(E), finis...);
        }
    };
     
    template<typename R,typename ...ArgsF>
    struct get_args_impl_2<R,0,ArgsF...>
    {
        template<typename Fc, typename ...Args, typename ...ArgsFE>
        static R apply(Fc function, ArgsF...argsfait, std::tuple<Args...> E,ArgsFE...finis )
        {
            return boost::bind(function, argsfait...)(finis...);
        }
    };
     
    template<typename R,unsigned int N>
    struct get_args_impl
    {
        template<typename Fc, typename ...Args, typename ...ArgsF, typename ...ArgsE>
        static R apply(Fc function, std::tuple<Args...> t, std::tuple<ArgsE...> E, ArgsF...argsfait)
        {
            return get_args_impl<R,N-1>::apply(function, t, E, std::get<N-1>(t), argsfait...);
        }
    };
     
    template<typename R>
    struct get_args_impl<R,0>
    {
        template<typename Fc, typename ...Args, typename ...ArgsF, typename ...ArgsE>
        static R apply(Fc function, std::tuple<Args...> t, std::tuple<ArgsE...> E, ArgsF...argsfait)
        {
            return get_args_impl_2<R,sizeof...(ArgsE), ArgsF...>::apply(function, argsfait..., E);
        }
    };
     
     
    template<typename R,typename Fc, typename ...Args, typename ...ArgsE>
    R my_bind(Fc function, const std::tuple<Args...>& t, const std::tuple<ArgsE...>& te)
    {
        return get_args_impl<R,sizeof...(Args)>::apply(function, const_cast<std::tuple<Args...>&>(t), const_cast<std::tuple<ArgsE...>&>(te));
    }
    Voici les erreurs :

    error:parameter packs must be at the end of the parameter list|
    error: parameter packs must be at the end of the parameter list|

    Je ne peux donc pas extraire les 2 tuples en même temps. Y a t-il un moyen d'y remédier ? De faire ce que je veux ?
    Et en mettant l'évènement avant la liste d'arguments variables ?

  5. #5
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    J'ai trouvé une solution qui compile dans certains cas et qui d'en d'autre m'affiche un message d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    instantiated from 'static void std::_Function_handler<void(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Functor = call_back<ArgsE>::make_callback(R&, fc, Args& ...) [with R = int, fc = int (*)(int, int), Args = {int, boost::arg<1>}, ArgsE = {int}]::<lambda(void*)>, _ArgTypes = {void*}]'|
    c:\gcc-g++\bin\..\lib\gcc\mingw32\4.5.0\include\c++\functional:2091|6|instantiated from 'std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = call_back<ArgsE>::make_callback(R&, fc, Args& ...) [with R = int, fc = int (*)(int, int), Args = {int, boost::arg<1>}, ArgsE = {int}]::<lambda(void*)>, _Res = void, _ArgTypes = {void*}, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = s|
    instantiated from 'static Callback call_back<ArgsE>::make_callback(R&, fc, Args& ...) [with R = int, fc = int (*)(int, int), Args = {int, boost::arg<1>}, ArgsE = {int}]'|
    instantiated from here|
    error: no matching function for call to 'my_bind(int (* const&)(int, int), const std::tuple<int&, boost::arg<1>&>&, std::tuple<int>)'|
    globalement, j'en déduis qu'il n'arrive pas a appeler my_bind avec les arguments que je lui est passé.

    Voici le code complet de l'exemple (il y a pas mal de chose inutile, donc il ne sert a rien de tout lire) :

    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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    #include <boost/bind.hpp>
    #include <functional>
    #include <unordered_map>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <queue>
    #include <boost/thread/thread.hpp>
    #include <windows.h>
    using namespace std;
     
    template<typename T, typename R, typename ...Args>
    class member_function
    {
        private :
            T* obj;
            R(T::*function)(Args...);
        public :
            member_function(T* ob, R(T::*func)(Args...)): obj(ob), function(func){}
            R operator()(Args...arg)
            {
                return (obj->*function)(arg...);
            }
    };
     
    template<typename T, typename R, typename ...Args>
    member_function<T,R,Args...> make_member(T*obj, R(T::*func)(Args...))
    {
        return member_function<T,R,Args...>(obj, func);
    }
     
    template<typename T, typename R, typename ...Args>
    member_function<T,R,Args...> make_member(T& obj, R(T::*func)(Args...))
    {
        return member_function<T,R,Args...>(&obj, func);
    }
     
    template<typename ...Args>
    class Evenement
    {
        private :
            std::tuple<Args...> my_args;
        public :
            Evenement(Args...args) : my_args(args...){}
            std::tuple<Args...>get_args(){return my_args;}
    };
     
     
    class Callback
    {
        private :
            std::function<void(void*)> function;
            bool is_function;
        public :
            Callback(const Callback& c)
            {
                this->function=c.function;
                is_function=c.is_function;
            }
            Callback(std::function<void(void*)> fc)
            {
                function=fc;
                is_function=true;
            }
            Callback(bool t)
            {
                is_function=t;
            }
            void operator()(void*even)
            {
                    function(even);
            }
            bool is_func()
            {
                return is_function;
            }
    };
    template<typename T>
    class ma_file
    {
        private :
            std::queue<T> queue;
            boost::mutex m;
            boost::mutex w;
            bool is_locked;
        public :
            ma_file(){is_locked=true;w.lock();}
            void add_element(const T& el)
            {
                boost::mutex::scoped_lock lock(m);
                queue.push(el);
                if(is_locked)
                {
                    w.unlock();
                    is_locked=false;
                }
            }
            T delete_element()
            {
                boost::mutex::scoped_lock lock(m);
                T tmp=queue.front();
                queue.pop();
                if(queue.empty())
                {
                    w.lock();
                    is_locked=true;
                }
                return tmp;
            }
            operator bool()
            {
                boost::mutex::scoped_lock lock(m);
                return !queue.empty();
            }
            void wait()
            {
                w.lock();
                w.unlock();
            }
    };
    template<typename R,unsigned int N>
    struct get_args_impl_2
    {
        template<typename Fc, typename ...Args, typename ...ArgsFE>
        static R apply(Fc function, std::tuple<Args...> E,ArgsFE...finis )
        {
            return get_args_impl_2<R,N-1>::apply(function, E, std::get<N-1>(E), finis...);
        }
    };
     
    template<typename R>
    struct get_args_impl_2<R,0>
    {
        template<typename Fc, typename ...Args, typename ...ArgsFE>
        static R apply(Fc function, std::tuple<Args...> E,ArgsFE...finis )
        {
            function(finis...);
        }
    };
     
    template<typename R,unsigned int N>
    struct get_args_impl
    {
        template<typename Fc, typename ...Args, typename ...ArgsF, typename ...ArgsE>
        static R apply(Fc function, std::tuple<Args...> t, std::tuple<ArgsE...> E, ArgsF...argsfait)
        {
            return get_args_impl<R,N-1>::apply(function, t, E, std::get<N-1>(t), argsfait...);
        }
    };
     
    template<typename R>
    struct get_args_impl<R,0>
    {
        template<typename Fc, typename ...Args, typename ...ArgsF, typename ...ArgsE>
        static R apply(Fc function, std::tuple<Args...> t, std::tuple<ArgsE...> E, ArgsF...argsfait)
        {
            return get_args_impl_2<R,sizeof...(ArgsE)>::apply(boost::bind(function, argsfait...), E);
        }
    };
     
     
    template<typename R,typename Fc, typename ...Args, typename ...ArgsE>
    R my_bind(const Fc function,std::tuple<Args&...>& t, std::tuple<ArgsE...>& te)
    {
        return get_args_impl<R,sizeof...(Args)>::apply(function, t, te);
    }
     
    template<typename ...ArgsE>
    struct call_back
    {
        template<typename R, typename fc, typename ...Args>
        static Callback make_callback(R& retour,fc function, Args&... param)
        {
            std::tuple<Args...> my_tuple(param...);
            return Callback
            (
                [
                    function, &retour,my_tuple
                ]
                (void*evens)
                    {
                        retour=my_bind<R, fc, Args...,ArgsE...> (function, my_tuple, ((Evenement<ArgsE...>*)(evens))->get_args());
                    }
            );
        }
    };
     
     
    class Object
    {
        private :
            ma_file<std::pair<Callback, void*>>* file_thread;
            std::unordered_map<std::string,std::vector<Callback>>Callbacks;
            bool has_key(std::string key)
            {
                if(Callbacks.find(key)==Callbacks.end())
                    return false;
                return true;
            }
            void handle_event(std::string key, void*even)
            {
                std::vector<Callback>&vect=Callbacks[key];
                for(unsigned int i=0;i<vect.size();i++)
                {
                    file_thread->add_element(std::pair<Callback, void*>(vect[i],even));
                }
            }
        public :
            void emit(std::string key, void* even=NULL)
            {
                handle_event(key,even);
            }
            bool add_event(std::string key, Callback fc)
            {
                if(has_key(key))
                {
                    std::vector<Callback>& vect=Callbacks[key];
                    vect.push_back(fc);
                    return false;
                }
                else
                {
                    std::vector<Callback> vect(1,fc);
                    Callbacks.insert(pair<std::string,std::vector<Callback>>(key,vect));
                    return true;
                }
            }
            Object(ma_file<std::pair<Callback, void*>>* mes_lancement) : file_thread(mes_lancement){};
     
    };
     
    class thread_argv
    {
        private :
            ma_file<std::pair<Callback, void*>>*file;
        public :
            thread_argv(ma_file<std::pair<Callback, void*>>* pfile)
            {
                file=pfile;
            }
            void operator()()
            {
                while(1)
                {
                    std::pair<Callback, void*> tmp(file->delete_element());
                    if((!(tmp.first.is_func())) && (tmp.second==NULL))
                        break;
                    tmp.first(tmp.second);
                    (*file).wait();
                }
            }
    };
     
    class app//Classe Singleton
    {
        private :
            boost::thread *my_thread;
            ma_file<std::pair<Callback,void*>>* file_thread;
        public :
            app()
            {
                file_thread=new ma_file<std::pair<Callback,void*>>();
                my_thread=new boost::thread(thread_argv(file_thread));
            }
            ~app(){delete my_thread;delete file_thread;}
            ma_file<std::pair<Callback,void*>>* get_file(){return file_thread;};
            int quit()
            {
                //app.emit("quit");
                file_thread->add_element(std::pair<Callback,void*>(Callback(false),NULL));
                my_thread->join();
     
                return 0;
            }
            int wait()
            {
                /*SDL_Event Event;
                while(1)
                {
                    SDL_WaitEvent(&Event);
                    switch(Event.type)
                    {
                        case SDL_UserEvent :
                            switch(*(int*)()
                        case Key_Event :
                    }
                }*/
                return 0;
            }
     
    };
     
    int test_func(int one, int two)
    {
        return one+two;
    }
     
    /*template<typename R, typename T1, typename T2, typename Fc, typename ...Args>
    R my_bind(T1 o, T2 t, Fc func,Args...arg)
    {
        return std::bind(func, arg...)(o,t);
    }*/
     
    int main()
    {
        app appli;
        Object a(appli.get_file());
     
        int b=10, c=40,d=5,e=20;
        Evenement<int> ymp(20);
        a.add_event("show",call_back<int>::make_callback(b, test_func, c,_1));
        a.emit(std::string("show"),(void*)(&ymp));
        appli.quit();
        std::cout<<"\nValeur après le declenchement de l'evenement : "<<b<<"\nValeur de c = "<<c<<"\n"<<d<<"\n"<<e<<"\n\n";
        return 0;
    }
    Quelqu'un aurait-il une idée ?

  6. #6
    Alp
    Alp est déconnecté
    Expert confirmé

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Une fonctions ne retourne qu'un seul objet. Là tu veux lui faire retourner une planqué d'objet. Pas possible. Ce n'est même pas une question de template.
    Là pour ça il faut utiliser des variadic tuples

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    oui je sait mais justement, l'objectif était d'extraire le tuple...
    Quelqu'un aurait-il une idée pourquoi ma nouvelle fontion my_bind ne marche pas tout le temps ?

  8. #8
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Merci a tous, mis j'ai trouvé la solution a mon problème :

    La voici :
    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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
     
    #ifndef BINDING_HPP_INCLUDED
    #define BINDING_HPP_INCLUDED
     
    #include <functional>
    #include <tuple>
    #include <boost/bind.hpp>
    template<int N>
    inline std::_Placeholder<N> set_event_arg()
    {
        return std::_Placeholder<N>();
    }
     
    template<typename T, typename R, typename ...Args>
    class member_function
    {
        private :
            T* obj;
            R(T::*function)(Args...);
        public :
            member_function(T* ob, R(T::*func)(Args...)): obj(ob), function(func){}
            R operator()(Args...arg)
            {
                return (obj->*function)(arg...);
            }
    };
     
     
    template<typename T, typename R, typename ...Args>
    member_function<T,R,Args...> make_member(T*obj, R(T::*func)(Args...))
    {
        return member_function<T,R,Args...>(obj, func);
    }
     
    template<typename T, typename R, typename ...Args>
    member_function<T,R,Args...> make_member(T& obj, R(T::*func)(Args...))
    {
        return member_function<T,R,Args...>(&obj, func);
    }
     
    template<typename R,unsigned int N>
    struct get_args_impl_2
    {
        template<typename Fc, typename ...Args, typename ...ArgsFE>
        static R apply(Fc function, std::tuple<Args...> E,ArgsFE...finis )
        {
            return get_args_impl_2<R,N-1>::apply(function, E, std::get<N-1>(E), finis...);
        }
    };
     
    template<typename R>
    struct get_args_impl_2<R,0>
    {
        template<typename Fc, typename ...Args, typename ...ArgsFE>
        static R apply(Fc function, std::tuple<Args...> E,ArgsFE...finis )
        {
                 return function(finis...);
        }
    };
     
    template<typename R,unsigned int N>
    struct get_args_impl
    {
        template<typename Fc, typename ...Args, typename ...ArgsF, typename ...ArgsE>
        static R apply(Fc function, std::tuple<Args...> t, std::tuple<ArgsE...> E, ArgsF...argsfait)
        {
            return get_args_impl<R,N-1>::apply(function, t, E, std::get<N-1>(t), argsfait...);
        }
    };
     
    template<typename R>
    struct get_args_impl<R,0>
    {
        template<typename Fc, typename ...Args, typename ...ArgsF, typename ...ArgsE>
        static R apply(Fc function, std::tuple<Args...> t, std::tuple<ArgsE...> E, ArgsF...argsfait)
        {
            return get_args_impl_2<R,sizeof...(ArgsE)>::apply(std::bind(function, argsfait...), E);
        }
    };
     
    template<typename R,typename Fc,typename ...ArgsE>
    struct stupid
    {
        template<typename ...Args>
        static R my_bind(Fc function,const std::tuple<Args...>& t, std::tuple<ArgsE...> te)
        {
            return get_args_impl<R,sizeof...(Args)>::apply(function, t, te);
        }
    };
     
     
     
     
    template<unsigned int N>
    struct get_args_impl_2_v2
    {
        template<typename Fc, typename ...Args, typename ...ArgsFE>
        static void apply(Fc function, std::tuple<Args...> E,ArgsFE...finis )
        {
            get_args_impl_2_v2<N-1>::apply(function, E, std::get<N-1>(E), finis...);
        }
    };
     
    template<>
    struct get_args_impl_2_v2<0>
    {
        template<typename Fc, typename ...Args, typename ...ArgsFE>
        static void apply(Fc function, std::tuple<Args...> E,ArgsFE...finis )
        {
                 function(finis...);
        }
    };
     
    template<unsigned int N>
    struct get_args_impl_v2
    {
        template<typename Fc, typename ...Args, typename ...ArgsF, typename ...ArgsE>
        static void apply(Fc function, std::tuple<Args...> t, std::tuple<ArgsE...> E, ArgsF...argsfait)
        {
            get_args_impl_v2<N-1>::apply(function, t, E, std::get<N-1>(t), argsfait...);
        }
    };
     
    template<>
    struct get_args_impl_v2<0>
    {
        template<typename Fc, typename ...Args, typename ...ArgsF, typename ...ArgsE>
        static void apply(Fc function, std::tuple<Args...> t, std::tuple<ArgsE...> E, ArgsF...argsfait)
        {
            get_args_impl_2_v2<sizeof...(ArgsE)>::apply(std::bind(function, argsfait...), E);
        }
    };
     
    template<typename Fc,typename ...ArgsE>
    struct stupid_v2
    {
        template<typename ...Args>
        static void my_bind(Fc function,const std::tuple<Args...>& t, std::tuple<ArgsE...> te)
        {
            get_args_impl_v2<sizeof...(Args)>::apply(function, t, te);
        }
    };
     
     
    #endif // BINDING_HPP_INCLUDED
    Je pense que le problème était du à une confusions de gcc entre ArgsE... et Args... C'est pourquoi, j'ai introduit la classe stupid.


    Je vous poste tout le projet pour pouvoir ajouter quelques questions
    Le projet est assez basique : il permet de voir une image de fond être étirée quand on rétrécie/agrandit la fenetre.


    main.cpp

    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
    #include "Evenement.hpp"
    #include "Callback.hpp"
    #include "binding.hpp"
    #include "app.hpp"
    #include "Object.hpp"
    #include <iostream>
    #include "Image.h"
     
    int main(int argc, char**argv)
    {
        app appli;
        Object a(appli);
        Image img("J:\\Jeu\\ciel.bmp");
        SDL_Surface*screen=appli.get_screen();
        Image img2(img.copier_redim(640u,480u));
        img2.blit(screen);
        SDL_Flip(screen);
        Image(Image::*cop)(unsigned int,unsigned int) =&Image::copier_redim;
        void(Image::*blit)(SDL_Surface*, unsigned int, unsigned int) =&Image::blit;
        appli.add_event("resize",Evenement<int,int>::make_callback(img2,make_member(img,cop),set_event_arg<1>(), set_event_arg<2>()));
        appli.add_event("resize",Evenement<int,int>::make_callback_void(make_member(img2,blit), screen, 0,0));
        appli.add_event("resize",Evenement<int,int>::make_callback_void(SDL_Flip, screen));
        appli.wait();
        SDL_Quit();
        return 0;
    }
    Callback.hpp
    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
     
    #ifndef CALLBACK_HPP_INCLUDED
    #define CALLBACK_HPP_INCLUDED
     
    #include <functional>
     
    class Callback
    {
        private :
            std::function<void(void*)> function;
        public :
            inline Callback(std::function<void(void*)> fc) : function(fc)
            {}
            inline void operator()(void*even)
            {
                function(even);
            }
    };
     
    #endif // CALLBACK_HPP_INCLUDED
    test_functions.hpp (ne sert presque à rien : il sert pour faire les tests)

    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
    #ifndef TEST_FUNCTIONS_HPP_INCLUDED
    #define TEST_FUNCTIONS_HPP_INCLUDED
     
    #include <SDL/SDL.h>
     
    int test_func(int& one, int two)
    {
        std::cout<<"one : "<<one<<" two : "<<two<<"\n";
        one=one+two;
        return one+two;
    }
     
     
    SDL_Surface*init()
    {
        freopen("CON", "w", stdout);
        freopen("CON", "r", stdin);
        freopen("CON", "w", stderr);
        SDL_Surface *screen;
        screen = SDL_SetVideoMode( 640, 480, 32, SDL_HWSURFACE|SDL_RESIZABLE );
        return screen;
    }
    #endif // TEST_FUNCTIONS_HPP_INCLUDED
    Image.h : wrapper c++ pour les SDL_Surface* (j'ai été obligé de supprimer tout les const pour un de mes problèmes)

    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
    #ifndef IMAGE_H_INCLUDED
    #define IMAGE_H_INCLUDED
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include <vector>
    #include <string>
     
    class Image
    {
        private :
            SDL_Surface *img;
        public :
            Image (SDL_Surface *image=NULL, bool copier=true);
            Image (const char *chm_img);
            Image (const Image &image);
            ~Image ();
     
            void blit (SDL_Surface *image, unsigned int x=0, unsigned int y=0) ;
            void blit (Image &image, unsigned int x=0, unsigned int y=0) ;
     
            void redim (double rapport);
            void redim (double rapport_x, double rapport_y);
            void redim (unsigned int nouv_taille);
            void redim (unsigned int nouv_l, unsigned int nouv_h);
     
            Image copier_redim (double rapport) ;
            Image copier_redim (double rapport_x, double rapport_y) ;
            Image copier_redim (unsigned int nouv_taille) ;
            Image copier_redim_h (unsigned int nouv_taille) ;
            Image copier_redim (unsigned int nouv_l, unsigned int nouv_h) ;
     
            void set_transparency(unsigned int);
            void set_transparency(unsigned int alpha, SDL_Rect zone);
            inline const SDL_Surface *obt_image ()
            { return img; }
     
            void delete_color(std::vector<Uint32> col);
            void delete_color(Uint32 col);
     
            void delete_color(bool (*fc)(Uint8 r, Uint8 v, Uint8 b, Uint8 a));
            void delete_color(bool (*fc)(Uint8 r, Uint8 v, Uint8 b));
            void delete_color(bool (*fc)(Uint8 r, Uint8 v, Uint8 b, Uint8 a, unsigned int x, unsigned int y));
            void delete_color(bool (*fc)(Uint8 r, Uint8 v, Uint8 b, unsigned int x, unsigned int y));
     
     
            void delete_transparent_borders();
            void keep_rectangle(unsigned int ,unsigned int , unsigned int , unsigned int);
            Image operator= (SDL_Surface *image);
            Image operator= (const Image &image);
            //bool saveAsPNG(const std::string filename);
            void set_alpha_perpixel();
     
            void set_color(unsigned int x, unsigned int y, Uint32 col);
            void set_color(unsigned int x, unsigned int y, Uint8 r, Uint8 v, Uint8 b, Uint8 a=0);
     
            Uint32 get_color(unsigned int x, unsigned int y);
            void get_color(unsigned int x, unsigned int y, Uint8& r, Uint8& v, Uint8& b, Uint8& a);
    };
    app.hpp

    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
    #ifndef APP_HPP_INCLUDED
    #define APP_HPP_INCLUDED
     
    #include <utility>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <unordered_map>
    #include "Callback.hpp"
    #include "Evenement.hpp"
    #include <SDL/SDL.h>
     
    class app
    {
        private :
            std::unordered_map<std::string,std::vector<Callback>>Callbacks;
            inline bool has_key(std::string key);
            void handle_event(std::string key, void*even);
            bool exit;
            int* err;
            SDL_Surface*screen;
        public :
            app();
            template<typename ...Args>
            inline void emit(std::string key, Evenement<Args...> even);
            inline void emit(std::string key);
            void wait();
            inline void quit();
            bool add_event(std::string key, Callback fc);
            bool add_event(std::string key, Callback fc, unsigned int pos);
            void show_callbacks();
            inline const std::unordered_map<std::string,std::vector<Callback>>& get_callbacks();
            SDL_Surface*get_screen();
    };
     
    #endif // APP_HPP_INCLUDED
    Object.hpp

    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
    #ifndef OBJECT_HPP_INCLUDED
    #define OBJECT_HPP_INCLUDED
     
    #include "app.hpp"
     
    class Object
    {
        private :
            std::unordered_map<std::string,std::vector<Callback>>Callbacks;
            inline bool has_key(std::string key);
            void handle_event(std::string key, void*even);
            app*application;
        public :
            Object(app& a);
            template<typename ...Args>
            inline void emit(std::string key, Evenement<Args...> even);
            inline void emit(std::string key);
            bool add_event(std::string key, Callback fc);
            bool add_event(std::string key, Callback fc, unsigned int pos);
            inline const std::unordered_map<std::string,std::vector<Callback>>& get_callbacks();
    };
     
    #endif // OBJECT_HPP_INCLUDED
    app.cpp

    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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    #include "app.hpp"
    #include "test_functions.hpp"
     
    SDL_Surface* app::get_screen()
    {
        return screen;
    }
     
    const std::unordered_map<std::string,std::vector<Callback>>& app::get_callbacks()
    {
        return Callbacks;
    }
     
    bool app::has_key(std::string key)
    {
        return !(Callbacks.find(key)==Callbacks.end());
    }
    void app::handle_event(std::string key, void*even)
    {
        std::vector<Callback>&vect=Callbacks[key];
        for(unsigned int i=0;i<vect.size();i++)
            (vect[i])(even);
    }
    app::app()
    {
        SDL_Init( SDL_INIT_EVERYTHING );
        screen=init();
        err=new int(0);
        add_event("resize",Evenement<int,int>::make_callback(screen,SDL_SetVideoMode, set_event_arg<1>(), set_event_arg<2>(),32, SDL_HWSURFACE|SDL_RESIZABLE));
        add_event("resize",Evenement<int,int>::make_callback_void(SDL_Flip, screen));
        add_event("sdl_quit",Evenement<>::make_callback_void(SDL_Quit));
    }
    template<typename ...Args>
    void app::emit(std::string key, Evenement<Args...> even)
    {
            handle_event(key,(void*)(&even));
    }
    void app::emit(std::string key)
    {
        if(has_key(key))
            handle_event(key,NULL);
    }
    void app::wait()
    {
        SDL_Event event;
        exit=false;
        while(!exit)
        {
            SDL_WaitEvent(&event);
            switch(event.type)
            {
                case SDL_VIDEORESIZE :
                    emit("resize", Evenement<int,int>(event.resize.w,event.resize.h));
                    break;
                case SDL_KEYDOWN :
                    emit("keyboard", Evenement<bool, SDL_keysym>(true,event.key.keysym));
                    break;
                case SDL_KEYUP :
                    emit("keyboard", Evenement<bool, SDL_keysym>(false,event.key.keysym));
                    break;
                case SDL_MOUSEBUTTONDOWN :
                    emit("mouse_button", Evenement<bool, Uint8,Uint16,Uint16>(true,event.button.which,event.button.x,event.button.y));
                    break;
                case SDL_MOUSEBUTTONUP :
                    emit("mouse_button", Evenement<bool, Uint8,Uint16,Uint16>(false,event.button.which,event.button.x,event.button.y));
                    break;
                case SDL_MOUSEMOTION :
                    emit("mouse_motion", Evenement<bool, Uint16,Uint16,Uint16,Uint16>(event.motion.state==SDL_PRESSED,event.motion.x,event.motion.y,event.motion.xrel,event.motion.yrel));
                    break;
                case SDL_VIDEOEXPOSE :
                    emit("video_expose");
                    break;
                case SDL_ACTIVEEVENT :
                    emit("window_sate",Evenement<bool>(event.active.gain==1));
                    break;
                case SDL_QUIT :
                    emit("sdl_quit");
                    break;
            }
            if(*err==-1)
                std::cout<<"Error";
     
        }
    }
    void app::quit()
    {
        exit=true;
    }
    bool app::add_event(std::string key, Callback fc)
    {
        if(has_key(key))
        {
            std::vector<Callback>& vect=Callbacks[key];
            vect.push_back(fc);
            return false;
        }
        else
        {
            std::vector<Callback> vect(1,fc);
            Callbacks.insert(std::pair<std::string,std::vector<Callback>>(key,vect));
            return true;
        }
    }
    bool app::add_event(std::string key, Callback fc, unsigned int pos)
    {
        if(has_key(key))
        {
            std::vector<Callback>& vect=Callbacks[key];
            if(pos<vect.size())
                vect.insert(vect.begin()+pos,fc);
            else
                vect.push_back(fc);
            return false;
        }
        else
        {
            std::vector<Callback> vect(1,fc);
            Callbacks.insert(std::pair<std::string,std::vector<Callback>>(key,vect));
            return true;
        }
    }
    void app::show_callbacks()
    {
        std::cout<<"showing callbacks";
        std::unordered_map<std::string,std::vector<Callback>>::iterator it;
        for(it=Callbacks.begin();it!=Callbacks.end();it++)
        {
            std::cout<<"\n"<<(*it).first<<" nb_func= "<<(*it).second.size();
        }
    }
    Object.cpp

    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
     
    #include "Object.hpp"
     
    const std::unordered_map<std::string,std::vector<Callback>>& Object::get_callbacks()
    {
        return Callbacks;
    }
     
    bool Object::has_key(std::string key)
    {
        return !(Callbacks.find(key)==Callbacks.end());
    }
    void Object::handle_event(std::string key, void*even)
    {
        std::vector<Callback>&vect=Callbacks[key];
        for(unsigned int i=0;i<vect.size();i++)
        {
            (vect[i])(even);
        }
    }
    Object::Object(app& a)
    {
        application=&a;
    }
    template<typename ...Args>
    void Object::emit(std::string key, Evenement<Args...> even)
    {
        if(has_key(key))
            handle_event(key,(void*)(&even));
    }
    void Object::emit(std::string key)
    {
        if(has_key(key))
            handle_event(key,NULL);
    }
    bool Object::add_event(std::string key, Callback fc)
    {
        if(has_key(key))
        {
            std::vector<Callback>& vect=Callbacks[key];
            vect.push_back(fc);
            return false;
        }
        else
        {
            std::vector<Callback> vect(1,fc);
            Callbacks.insert(std::pair<std::string,std::vector<Callback>>(key,vect));
            return true;
        }
    }
     
    bool Object::add_event(std::string key, Callback fc, unsigned int pos)
    {
        if(has_key(key))
        {
            std::vector<Callback>& vect=Callbacks[key];
            if(pos<vect.size())
                vect.insert(vect.begin()+pos,fc);
            else
                vect.push_back(fc);
            return false;
        }
        else
        {
            std::vector<Callback> vect(1,fc);
            Callbacks.insert(std::pair<std::string,std::vector<Callback>>(key,vect));
            return true;
        }
    }

    Mes 2 problèmes sont : Quel est le type d'une fonction avec des arguments par défaut ?

    ce qui m'éviterais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    appli.add_event("resize",Evenement<int,int>::make_callback_void(make_member(img2,blit), screen,0,0));
    Comment gérer les const ? car si le type est const, gcc me dit qu'il ne peut pas appeler make_callback.

    De plus, y-a t-il plus simple que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Image(Image::*cop)(unsigned int,unsigned int) =&Image::copier_redim;
        void(Image::*blit)(SDL_Surface*, unsigned int, unsigned int) =&Image::blit;
    ou un cast pour indiquer quelle "version" de la fonction je veux ?

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

Discussions similaires

  1. Question de liaison avec des template
    Par dj.motte dans le forum Langage
    Réponses: 18
    Dernier message: 26/09/2008, 17h42
  2. Structure des fichiers avec des templates
    Par Trunks dans le forum C++
    Réponses: 2
    Dernier message: 26/08/2008, 21h11
  3. Réponses: 1
    Dernier message: 22/08/2007, 15h48
  4. Réponses: 6
    Dernier message: 29/11/2006, 11h56
  5. Créer un type matrice avec des templates
    Par souading3000 dans le forum C++
    Réponses: 2
    Dernier message: 15/06/2006, 11h24

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