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++

Vue hybride

NoIdea difficulté avec des templates... 08/08/2010, 12h49
3DArchi Salut, La piste est... 11/08/2010, 15h20
NoIdea Merci 3dArchi, de m'avoir... 11/08/2010, 19h17
3DArchi Salut Normale que ton code... 12/08/2010, 07h00
NoIdea J'ai trouvé une solution qui... 12/08/2010, 13h09
Alp Là pour ça il faut utiliser... 13/08/2010, 20h02
Message précédent Message précédent   Message suivant Message suivant
  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 ?

+ 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