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

Langage C++ Discussion :

Quelques questions à propos du langage lui même.


Sujet :

Langage C++

  1. #81
    Invité
    Invité(e)
    Par défaut
    Mmmm avec les placeholders ça ne fonctionne que dans ce cas là :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void(*f)(int, int) = &foo;
    odfaeg::FastDelegate<void> f1(std::bind(f, 3, _1), 3);
    f1.setParams(4);
    f1();
    std::cout << std::endl;

    Mais bon je jette l'éponge, je ne vois pas du tout comment gérer ça avec des placeholders, surtout qu'ils n'ont pas de type, et en plus leur type n'est pas le même que le type des paramètres du pointeur de fonction, donc, je dois arriver à stocker dans un tuple des éléments de types complètement différent que ceux que je fournis à la classe et puis les transformer lors de l'appel du foncteur. (Je ne vois pas du tout comment faire cela)

  2. #82
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    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
     
    //function_dyn.hpp
     
    #include<functional>
    #include<utility>
     
    namespace odfaeg
    {
    //Foncteur incluant une conversion pour les pointeurs de fonction membre
     
    //(Interne) Couche incluant la conversion en cas de pointeurs de fonction membre
    template<class C, class R, class... ArgT>
    struct wrap_dyn
    {
    	wrap_dyn(R (C::*pf)(ArgT...))
    		: pfunc(pf)
    	{}
     
    	template<class O, class... ArgU>
    	R operator()(O* o, ArgU&&... arg) const
    	{
    		if(dynamic_cast<C*>(o))
    			return (dynamic_cast<C*>(o)->*pfunc)(std::forward<ArgU>(arg)...);
    	}
    	template<class... ArgU>
    	R operator()(C* c, ArgU&&... arg) const
    	{ return (c->*pfunc)(std::forward<ArgU>(arg)...); }
     
    private:
    	R (C::*pfunc)(ArgT...);
    };
     
    //(Utilisateur) Classe métier, se substitue à std::function
    template<class>
    class function_dyn;
     
    template<class R, class... ArgT>
    class function_dyn<R(ArgT...)>
    	: std::function<R(ArgT...)>
    {
    	using base = std::function<R(ArgT...)>;
     
    public:
    	template<class F>
    	function_dyn(F&& f)
    		: base(std::forward<F>(f))
    	{}
    	template<class C, class... ArgU>
    	function_dyn(R (C::*pf)(ArgU...))
    		: base(wrap_dyn<C,R,ArgU...>(pf))
    	{}
     
    	using base::operator();
    };
     
    }
    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
     
    //ref_val.hpp
     
    #include<functional>
    #include<memory>
     
    namespace odfaeg
    {
     
    //Type-erasure pour stocker une référence ou une valeur
     
    //(Interne) Interface pour la donnée du type-erasure
    template<class T>
    struct ref_val_i
    {
    	//Constructeur, destructeur
    	ref_val_i()=default;
    	virtual ~ref_val_i(){}
     
    	//Copie
    	virtual std::unique_ptr<ref_val_i> clone() const =0;
     
    	//Accès à la donnée
    	virtual T& get() =0;
     
    protected:
    	ref_val_i(const ref_val_i&){}
     
    	ref_val_i& operator=(const ref_val_i&)
    	{ return *this; }
    };
     
    //(Interne) Donnée de type référence
    template<class T>
    struct ref : ref_val_i<T>
    {
    	ref(const std::reference_wrapper<T>& r)
    		: data(r)
    	{}
     
    	std::unique_ptr<ref_val_i<T>> clone() const
    	{ return std::make_unique<ref>(*this); }
     
    	T& get()
    	{ return data.get(); }
     
    private:
    	std::reference_wrapper<T> data;
    };
     
    //(Interne) Donnée de type valeur
    template<class T>
    struct val : ref_val_i<T>
    {
    	template<class U>
    	val(U&& t)
    		: data(std::forward<U>(t))
    	{}
     
    	std::unique_ptr<ref_val_i<T>> clone() const
    	{ return std::make_unique<val>(*this); }
     
    	T& get()
    	{ return data; }
     
    private:
    	T data;
    };
     
    //(Utilisateur) Classe métier du type-erasure
    template<class T>
    struct ref_val
    {
    	template<class U>
    	ref_val(U&& t)
    		: rv(std::make_unique<val<T>>(std::forward<U>(t)))
    	{}
    	ref_val(const std::reference_wrapper<T>& r)
    		: rv(std::make_unique<ref<T>>(r))
    	{}
    	ref_val(std::reference_wrapper<T>& r)
    		: rv(std::make_unique<ref<T>>(r))
    	{}
    	ref_val(std::reference_wrapper<T>&& r)
    		: rv(std::make_unique<ref<T>>(r))
    	{}
    	ref_val(const ref_val& rhs)
    		: rv(rhs.rv->clone())
    	{}
     
    	ref_val& operator=(const ref_val& rhs)
    	{ rv=rhs.rv->clone(); return *this; }
     
    	T& get() const
    	{ return rv->get(); }
     
    private:
    	std::unique_ptr<ref_val_i<T>> rv;
    };
     
    }
    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
     
    //to_store.hpp
     
    #include<functional>
    #include<type_traits>
     
    namespace odfaeg
    {
     
    //Classe de trait pour déterminer le type à stocker
     
    //(Interne) Cas général
    template<class T>
    struct to_store_impl
    { using type = T; };
     
    //(Interne) Spécilisation pour les références
    template<class T>
    struct to_store_impl<std::reference_wrapper<T>>
    { using type = T; };
     
    //(Utilisateur) Classe de trait
    template<class T>
    struct to_store
    	: to_store_impl<std::decay_t<T>>
    {};
     
    //(Utilisateur) Alias pour la classe de trait
    template<class T>
    using to_store_t = typename
    	to_store<T>::type;
     
    }
    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
     
    //delegate.hpp
     
    #include<memory>
     
    #include<boost/mpl/apply.hpp>
    #include<boost/mpl/if.hpp>
    #include<boost/mpl/placeholders.hpp>
     
    //#include"function_dyn.hpp"
    //#include"ref_val.hpp"
    //#include"to_store.hpp"
     
    namespace odfaeg
    {
     
    namespace mpl = boost::mpl;
     
    using mpl::placeholders::_;
     
    //Système de callback incluant un stockage des paramètres
     
    //(Interne) Classe interface pour le type-erasure
    template<class R>
    struct delegate_i
    {
    	delegate_i() =default;
    	virtual ~delegate_i(){}
     
    	virtual std::unique_ptr<delegate_i> clone() const =0;
     
    	virtual R operator()() const = 0;
     
    protected:
    	delegate_i(const delegate_i&){}
     
    	delegate_i& operator=(const delegate_i&)
    	{ return *this; }
    };
     
    //(Interne) Classe générique d'implémentation du type-erasure
    template<class PFun, class R, class... ArgT>
    struct delegate_impl : delegate_i<R>
    {
    	template<class F, class... ArgU>
    	delegate_impl(F&& f, ArgU&&... arg)
    		: func(std::forward<F>(f))
    		, param(std::forward<ArgU>(arg)...)
    	{}
     
    	std::unique_ptr<delegate_i<R>> clone() const
    	{ return std::make_unique<delegate_impl>(*this); }
     
    	R operator()() const
    	{ return call(std::make_index_sequence<sizeof...(ArgT)>()); }
    	template<class... ArgU>
    	void set(ArgU&&... arg)
    	{ param=std::make_tuple(std::forward<ArgU>(arg)...); }
     
    private:
    	template<std::size_t... I>
    	R call(std::index_sequence<I...>) const
    	{ return func(std::get<I>(param).get()...); }
     
    	typename mpl::apply<
    		PFun,R(ArgT&...)
    	>::type func;
    	std::tuple<ref_val<ArgT>...> param;
    };
     
    //(Utilisateur) Classe métier du système
    template<
    	class R,
    	class PFun =function_dyn<_>,
    	class PConv =mpl::if_<
    		std::is_same<std::decay<_>,const char*>,
    		std::string,_
    	>
    >
    struct delegate {
    	template<class F, class... Arg>
    	delegate(F&& f, Arg&&... arg) :
    		data(std::make_unique<delegate_impl<
    				PFun,R,
    				typename mpl::apply<to_store<PConv>,Arg>::type...
    			>>
    			(std::forward<F>(f),std::forward<Arg>(arg)...)
    		)
    	{}
    	delegate(const delegate& rhs)
    		: data(rhs.data->clone())
    	{}
    	delegate(delegate& rhs)
    		: data(rhs.data->clone())
    	{}
    	delegate(delegate&& rhs) =default;
     
    	delegate& operator=(const delegate& rhs)
    	{ return operator=(delegate(rhs)); }
    	delegate& operator=(delegate&&) =default;
     
    	R operator()() const
    	{ return (*data)(); }
    	template<class... Arg>
    	void set(Arg&&... arg)
    	{
    		using DynamicType = delegate_impl<
    			PFun,R,
    			typename mpl::apply<to_store<PConv>,Arg>::type...
    		>*;
     
    		if(dynamic_cast<DynamicType>(data.get()))
    			dynamic_cast<DynamicType>(data.get())->set(std::forward<Arg>(arg)...);
    	}
     
    private:
    	std::unique_ptr<delegate_i<R>> data;
    };
     
    //(Utilisateur) Fonctions de création externe
    template<class F, class... Arg>
    delegate<decltype(std::declval<F>()(std::declval<Arg>()...))> make_delegate(F&& f, Arg&&... arg)
    { return {std::forward<F>(f),std::forward<Arg>(arg)...}; }
     
    template<class R, class... Arg>
    delegate<R> make_delegate(R (*pf)(std::decay_t<Arg>...), Arg&&... arg)
    { return {pf,std::forward<Arg>(arg)...}; }
     
    template<class R, class C, class... ArgT, class... ArgU>
    delegate<R> make_delegate(R (C::*pf)(ArgT...), ArgU&&... arg)
    { return {pf,std::forward<ArgU>(arg)...}; }
     
    template<class R, class C, class... Arg>
    delegate<R> make_delegate(R (C::*pf)(std::decay_t<Arg>...), C* c, Arg&&... arg)
    { return {pf,c,std::forward<Arg>(arg)...}; }
     
    }
    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
     
    #include<iostream>
    #include<string>
     
    using namespace std::literals;
    using namespace std::placeholders;
     
    void foo(int i)
    { std::cout << i; }
     
    struct A {
    	void foo(int i)
    	{ std::cout << i; }
    };
     
    struct B {
    	virtual void foo()
    	{ std::cout << 1; }
    	virtual ~B();
    };
     
    B::~B(){}
     
    struct C : B { void foo(); };
     
    void C::foo(){ std::cout << 2; }
     
    struct D {
    	void operator()(int i) const
    	{ std::cout << i; }
    };
     
    void bar(const std::string& s)
    { std::cout << s; }
     
    int goo(int i)
    { return i; }
     
    void hoo(int i)
    { std::cout << i; }
     
    void hoo(int* i)
    { std::cout << *i; }
     
    struct E
    {
    	void foo(int i)
    	{ std::cout << i; }
     
    	void foo(int* i)
    	{ std::cout << *i; }
    };
     
    int main(){
    	auto f1 = odfaeg::make_delegate(foo,3);
    	f1();
    	f1.set(4);
    	f1();
    	std::cout << std::endl;
     
    	auto f2 = odfaeg::make_delegate(
    		[](int i){ std::cout << i; },
    		5
    	);
    	f2();
    	f2.set(6);
    	f2();
    	std::cout << std::endl;
     
    	int i = 7;
    	auto f3 = odfaeg::make_delegate(
    		[i](int j){ std::cout << i << j; },
    		8
    	);
    	f3();
    	f3.set(9);
    	f3();
    	std::cout << std::endl;
     
    	A a;
    	auto f4 = odfaeg::make_delegate(&A::foo,&a,10);
    	f4();
    	f4.set(&a,11);
    	f4();
    	std::cout << std::endl;
     
    	auto f5 = f1;
    	f5();
    	f5=f3;
    	f5();
    	std::cout << std::endl;
     
    	C c;
    	B* b = &c;
    	auto f6 = odfaeg::make_delegate(&C::foo,b);
    	f6();
    	f6.set(&c);
    	f6();
    	std::cout << std::endl;
     
    	auto f7 = odfaeg::make_delegate(D(),12);
    	f7();
    	f7.set(13);
    	f7();
    	std::cout << std::endl;
     
    	auto f8 = odfaeg::make_delegate(bar,"ab"s);
    	f8();
    	f8.set("abc"s);
    	f8();
    	std::cout << std::endl;
     
    	auto f9 = odfaeg::make_delegate(bar,"de");
    	f9();
    	f9.set("def");
    	f9();
    	std::cout << std::endl;
     
    	auto f10 = odfaeg::make_delegate(goo,14);
    	std::cout << f10();
    	f10.set(15);
    	std::cout << f10();
    	std::cout << std::endl;
     
    	auto f11 = odfaeg::make_delegate(foo,std::ref(i));
    	f11();
    	i=16;
    	f11();
    	std::cout << std::endl;
     
    	auto f12 = odfaeg::make_delegate(std::bind(foo,_1),17);
    	f12();
    	f12.set(18);
    	f12();
    	std::cout << std::endl;
     
    	auto f13 = odfaeg::make_delegate<void>(hoo,i);
    	f13();
    	std::cout << std::endl;
     
    	auto f14 = odfaeg::make_delegate<void>(hoo,&i);
    	f14();
    	std::cout << std::endl;
     
    	E e;
    	auto f15 = odfaeg::make_delegate<void>(&E::foo,&e,i);
    	f15();
    	std::cout << std::endl;
     
    	auto f16= odfaeg::make_delegate<void>(&E::foo,&e,&i);
    	f16();
    	std::cout << std::endl;
    }

  3. #83
    Invité
    Invité(e)
    Par défaut
    Merci, mais je suis parti plutôt sur quelque chose de plus simple, plutôt de ce goût là.

    Code cpp : 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
     
    #ifndef ODFAEG_FAST_DELEGATE_HPP
    #define ODFAEG_FAST_DELEGATE_HPP
    #include <functional>
    #include <iostream>
    #include "export.hpp"
    #include "erreur.h"
    #include <tuple>
    #include <utility>
    #include <memory>
    namespace odfaeg {
    template<class T>
    struct IRefVal {
    	IRefVal()=default;
    	virtual T& get() =0;
    	virtual std::unique_ptr<IRefVal<T>> clone() const = 0;
    	virtual void set(const T& v) = 0;
    	virtual ~IRefVal(){}
     
    protected:
    	IRefVal(const IRefVal&){}
    	IRefVal& operator=(const IRefVal&)
    	{ return *this; }
    };
     
    template<class T>
    struct Ref : IRefVal<T> {
    	Ref(const std::reference_wrapper<T>& r)
    		: ref(r)
    	{}
    	T& get()
    	{ return ref.get(); }
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<Ref>(*this); }
        void set(const T& v) {
            ref = v;
        }
    private:
    	std::reference_wrapper<T> ref;
    };
     
    template<class T>
    struct Val : IRefVal<T> {
    	Val(const T& t)
    		: val(t)
    	{}
        void set(const T& v) {
            val = v;
        }
    	T& get()
    	{ return val; }
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<Val>(*this); }
     
    private:
    	T val;
    };
    template<class T>
    struct Pointer : IRefVal<T> {
    	Pointer(const T* t)
    		: val(t)
    	{}
        void set(const T& v) {
            val = &v;
        }
    	T& get()
    	{ return val; }
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<Pointer<T>>(*this); }
     
    private:
    	T val;
    };
    template<class T>
    struct RefVal {
    	RefVal(const T& t)
    	: rv(std::make_unique<Val<T>>(t))
    	{}
    	RefVal(const std::reference_wrapper<T>& r)
    	: rv(std::make_unique<Ref<T>>(r))
    	{}
    	RefVal(const T*& p)
    	: rv(std::make_unique<Pointer<T>>(p))
    	{}
    	RefVal(const RefVal& rhs)
        {
            rv = rhs.rv->clone();
        }
    	RefVal& operator=(const RefVal& rhs)
    	{ rv=rhs.rv->clone(); return *this; }
    	void operator= (const T& t) {
            rv->set(t);
    	}
    	T& get() const
    	{ return rv->get(); }
     
    private:
    	std::unique_ptr<IRefVal<T>> rv;
    };
    template<class R, class C, class... ArgT>
    struct DynamicWrapper {
    	DynamicWrapper(R(C::*pf)(ArgT...)) : pfunc(pf){}
    	template<class O, class... ArgU>
    	R operator()(O* o, ArgU&&... arg) const
    	{
    		if(dynamic_cast<C*>(o))
    			return (dynamic_cast<C*>(o)->*pfunc)(std::forward<ArgU>(arg)...);
    	}
    private:
    	R (C::*pfunc)(ArgT...);
    };
    template<class F>
    class DynamicFunction;
     
    template<class R, class... ArgT>
    class DynamicFunction<R(ArgT...)>
    	: std::function<R(ArgT...)>
    {
    	using Base = std::function<R(ArgT...)>;
     
    public:
    	template<class F>
    	DynamicFunction(F&& f) : Base(std::forward<F>(f))
    	{}
    	template<class C, class... ArgU>
    	DynamicFunction(R (C::*pf)(ArgU...))
    		: Base(DynamicWrapper<R,C,ArgU...>(pf))
    	{}
     
    	using Base::operator();
    };
    template<class R>
    struct Delegate {
    	Delegate() =default;
    	virtual std::unique_ptr<Delegate> clone() const = 0;
    	virtual R operator()() = 0;
    	virtual ~Delegate(){}
     
    protected:
    	Delegate(const Delegate&){}
    	Delegate& operator=(const Delegate&)
    	{ return *this; }
    };
     
    template<class R, class... ArgT>
    struct FastDelegateImpl : Delegate<R> {
    	template<class F, class... ArgU>
    	FastDelegateImpl(F&& f, ArgU&&... arg)
    		: func(std::forward<F>(f))
    		, param(std::forward<ArgU>(arg)...)
    	{}
    	std::unique_ptr<Delegate<R>> clone() const
    	{ return std::make_unique<FastDelegateImpl>(*this); }
    	R operator()()
    	{ return call(std::make_index_sequence<sizeof...(ArgT)>()); }
    	template<class... ArgU>
    	void setParams(ArgU&&... arg)
    	{ param=std::make_tuple(std::forward<ArgU>(arg)...); }
     
    private:
    	template<std::size_t... I>
    	R call(std::index_sequence<I...>)
    	{ return func(std::get<I>(param).get()...); }
     
    	std::function<R(ArgT&...)> func;
    	std::tuple<RefVal<ArgT>...> param;
    };
    template<class R>
    struct FastDelegate {
    	template<class F, class... Arg>
    	FastDelegate(F&& f, Arg&&... arg) :
    		delegate(std::make_unique
    			<FastDelegateImpl<R,ToStore_t<Arg>...>>
    			(std::forward<F>(f),std::forward<Arg>(arg)...)
    		)
    	{}
    	FastDelegate(FastDelegate& rhs)
    		: delegate(rhs.delegate->clone())
    	{}
    	FastDelegate(const FastDelegate& rhs)
    		: delegate(rhs.delegate->clone())
    	{}
    	FastDelegate(FastDelegate&& rhs) =default;
    	FastDelegate& operator=(const FastDelegate& rhs)
    	{ return operator=(FastDelegate(rhs)); }
    	FastDelegate& operator=(FastDelegate&&) =default;
    	R operator()() const
    	{ return (*delegate)(); }
    	template<class... Arg>
    	void setParams(Arg&&... arg)
    	{
    		using DynamicType =
    			FastDelegateImpl<R,ToStore_t<Arg>...>*;
     
    		if(dynamic_cast<DynamicType>(delegate.get()))
    			dynamic_cast<DynamicType>(delegate.get())->setParams(std::forward<Arg>(arg)...);
    	}
     
    private:
    	std::unique_ptr<Delegate<R>> delegate;
    };
    }
    #endif // PLACE_HOLDERS_H

    T'a oublié de faire la spécialisation pour les pointeurs pour IRefVal. (A moins que c'est ce que fait la classe de trait qui utilise std::decay ?)

    Bref, c'est pour ça que ça ne marchais pas avec la "dynamic function".

    Avec les placeholders là par contre je ne sais pas si il y a moyen de faire un type erasure avec ça, c'est pour cela que je ne pense pas les utiliser.

  4. #84
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Tu appelles ça simple?

    Essaie au minimum d'essayer ce qui t'es proposé.
    Quand on pose une question à une communauté d'experts, qui prennent sur le temps personnel pour aider, on a l'intelligence d'écouter et essayer la solution.

    Tu va vraiment finir par fâcher.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #85
    Invité
    Invité(e)
    Par défaut
    Ok mais je fais comment si je veux utiliser ce code proposé en mode type erasure ?

    De plus l'interface n'a pas de méthode setParams.

  6. #86
    Invité
    Invité(e)
    Par défaut Ca y est!
    Ce code marche chez moi :

    Code cpp : 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
     
    #ifndef ODFAEG_FAST_DELEGATE_HPP
    #define ODFAEG_FAST_DELEGATE_HPP
    #include <functional>
    #include <iostream>
    #include "export.hpp"
    #include "erreur.h"
    #include <tuple>
    #include <utility>
    #include <memory>
    #include<boost/mpl/apply.hpp>
    #include<boost/mpl/if.hpp>
    #include<boost/mpl/placeholders.hpp>
    namespace odfaeg {
    template<class T>
    struct IRefVal {
    	IRefVal()=default;
    	virtual T& get() =0;
    	virtual std::unique_ptr<IRefVal<T>> clone() const = 0;
    	virtual ~IRefVal(){}
     
    protected:
    	IRefVal(const IRefVal&){}
    	IRefVal& operator=(const IRefVal&)
    	{ return *this; }
    };
     
    template<class T>
    struct Ref : IRefVal<T> {
    	Ref(const std::reference_wrapper<T>& r)
    		: ref(r)
    	{}
    	T& get()
    	{ return ref.get(); }
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<Ref>(*this); }
    private:
    	std::reference_wrapper<T> ref;
    };
     
    template<class T>
    struct Val : IRefVal<T> {
    	Val(const T& t)
    		: val(t)
    	{}
    	T& get()
    	{ return val; }
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<Val>(*this); }
     
    private:
    	T val;
    };
    template<class T>
    struct Pointer : IRefVal<T> {
    	Pointer(const T* t)
    		: val(t)
    	{}
    	T& get()
    	{ return val; }
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<Pointer<T>>(*this); }
     
    private:
    	T val;
    };
    template<class T>
    struct RefVal {
    	RefVal(const T& t)
    	: rv(std::make_unique<Val<T>>(t))
    	{}
    	RefVal(const std::reference_wrapper<T>& r)
    	: rv(std::make_unique<Ref<T>>(r))
    	{}
    	RefVal(const T*& p)
    	: rv(std::make_unique<Pointer<T>>(p))
    	{}
    	RefVal(const RefVal& rhs)
        {
            rv = rhs.rv->clone();
        }
    	RefVal& operator=(const RefVal& rhs)
    	{ rv=rhs.rv->clone(); return *this; }
    	T& get() const
    	{ return rv->get(); }
     
    private:
    	std::unique_ptr<IRefVal<T>> rv;
    };
    //Classe de trait pour déterminer le type à stocker
     
    //(Interne) Cas général
    template<class T>
    struct ToStoreImpl
    { using type = T; };
     
    template<class T>
    struct ToStoreImpl<std::reference_wrapper<T>>
    { using type = T; };
     
    template<class T>
    struct ToStore
    	: ToStoreImpl<std::remove_reference_t<T>>
    {};
     
    template<class T>
    using ToStore_t = typename
    	ToStore<T>::type;
    template<class R, class C, class... ArgT>
    struct DynamicWrapper {
    	DynamicWrapper(R(C::*pf)(ArgT...)) : pfunc(pf){}
    	template<class O, class... ArgU>
    	R operator()(O* o, ArgU&&... arg) const
    	{
    		if(dynamic_cast<C*>(o))
    			return (dynamic_cast<C*>(o)->*pfunc)(std::forward<ArgU>(arg)...);
            throw Erreur(0, "Invalid cast : types are nor polymorphic!", 1);
    	}
    private:
    	R (C::*pfunc)(ArgT...);
    };
    template<class F>
    class DynamicFunction;
     
    template<class R, class... ArgT>
    class DynamicFunction<R(ArgT...)>
    	: std::function<R(ArgT...)>
    {
    	using Base = std::function<R(ArgT...)>;
     
    public:
    	template<class F>
    	DynamicFunction(F&& f) : Base(std::forward<F>(f))
    	{}
    	template<class C, class... ArgU>
    	DynamicFunction(R (C::*pf)(ArgU...))
    		: Base(DynamicWrapper<R,C,ArgU...>(pf))
    	{}
     
    	using Base::operator();
    };
    template<class R>
    struct Delegate {
    	Delegate() =default;
    	virtual std::unique_ptr<Delegate> clone() const = 0;
    	virtual R operator()() = 0;
    	virtual ~Delegate(){}
     
    protected:
    	Delegate(const Delegate&){}
    	Delegate& operator=(const Delegate&)
    	{ return *this; }
    };
     
    template<class R, class... ArgT>
    struct FastDelegateImpl : Delegate<R> {
        template<class F, class... ArgU>
    	FastDelegateImpl(F&& f, ArgU&&... arg)
    		: func(std::forward<F>(f))
    		, param(std::forward<ArgU>(arg)...)
    	{}
    	std::unique_ptr<Delegate<R>> clone() const
    	{ return std::make_unique<FastDelegateImpl>(*this); }
    	R operator()()
    	{ return call(std::make_index_sequence<sizeof...(ArgT)>()); }
    	template<class... ArgU>
    	void setParams(ArgU&&... arg)
    	{ param=std::make_tuple(std::forward<ArgU>(arg)...); }
     
    private:
    	template<std::size_t... I>
    	R call(std::index_sequence<I...>)
    	{ return func(std::get<I>(param).get()...); }
     
    	std::function<R(ArgT&...)> func;
    	std::tuple<RefVal<ArgT>...> param;
    };
    template<class R>
    struct FastDelegate {
        FastDelegate() {}
    	template<class F, class... Arg>
    	FastDelegate(F&& f, Arg&&... arg) :
    		delegate(std::make_unique
    			<FastDelegateImpl<R,ToStore_t<Arg>...>>
    			(std::forward<F>(f),std::forward<Arg>(arg)...)
    		)
    	{}
    	FastDelegate(FastDelegate& rhs)
    		: delegate(rhs.delegate->clone())
    	{}
    	FastDelegate(const FastDelegate& rhs)
    		: delegate(rhs.delegate->clone())
    	{}
    	FastDelegate(FastDelegate&& rhs) =default;
    	FastDelegate& operator=(const FastDelegate& rhs)
    	{ return operator=(FastDelegate(rhs)); }
    	FastDelegate& operator=(FastDelegate&&) =default;
    	R operator()() const
    	{ return (*delegate)(); }
    	template<class... Arg>
    	void setParams(Arg&&... arg)
    	{
    		using StaticType =
    			FastDelegateImpl<R,ToStore_t<Arg>...>*;
    		static_cast<StaticType>(delegate.get())->setParams(std::forward<Arg>(arg)...);
    	}
    private:
    	std::unique_ptr<Delegate<R>> delegate;
    };
    }
    #endif

    Dans setParams, j'ai juste dû remplacer le dynamic_cast par un static_cast car sinon, le cast échouait si la fonction de callback est template pour les fonctions dynamique.

+ Répondre à la discussion
Cette discussion est résolue.
Page 5 sur 5 PremièrePremière 12345

Discussions similaires

  1. Réponses: 12
    Dernier message: 13/06/2011, 09h28
  2. Réponses: 0
    Dernier message: 21/02/2011, 15h58
  3. Réponses: 1
    Dernier message: 11/03/2010, 12h01
  4. Quelques questions à propos de DreamShield
    Par kahoerre dans le forum Dreamshield
    Réponses: 10
    Dernier message: 10/06/2009, 09h44
  5. Quelques question à propos des technologies RAID
    Par DranDane dans le forum Composants
    Réponses: 6
    Dernier message: 12/08/2008, 12h40

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