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. #41
    Invité
    Invité(e)
    Par défaut
    Re,
    j'ai installé gcc 4.9.1 sur ubuntu mais..., il ne me trouve pas les fonctions std::make_unique, std::make_index_sequence, etc... (Les nouvelles du c++14 quoi)

    T'a fait comment pour l'installer ?

  2. #42
    Invité
    Invité(e)
    Par défaut
    Non c'est bon il fallait rajouté l'option -std=c++14.

  3. #43
    Invité
    Invité(e)
    Par défaut
    Bon pas de problème pour les fonctions sans type de retour, mais avec type de retour il me confond les 2 :

    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
     
    typedef void DefaultVoid;
    template<class C, class... ArgT>
    struct DynamicWrapper {
    	DynamicWrapper(void (C::*pf)(ArgT...)) : pfunc(pf){}
    	template<class O, class... ArgU>
    	void operator()(O* o, ArgU&&... arg) const
    	{
    		if(dynamic_cast<C*>(o))
    			(dynamic_cast<C*>(o)->*pfunc)(std::forward<ArgU>(arg)...);
    	}
    private:
    	void (C::*pfunc)(ArgT...);
    };
     
    template<class F>
    class DynamicFunction;
     
    template<class... ArgT>
    class DynamicFunction<void(ArgT...)>
    	: std::function<void(ArgT...)>
    {
    	using Base = std::function<void(ArgT...)>;
     
    public:
    	template<class F>
    	DynamicFunction(F&& f) : Base(std::forward<F>(f))
    	{}
    	template<class C, class... ArgU>
    	DynamicFunction(void (C::*pf)(ArgU...))
    		: Base(DynamicWrapper<C,ArgU...>(pf))
    	{}
     
    	using Base::operator();
    };
    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(void (C::*pf)(ArgU...))
    		: Base(DynamicWrapper<C,ArgU...>(pf))
    	{}
     
    	using Base::operator();
    };
     
    struct Delegate {
    	Delegate() =default;
    	virtual std::unique_ptr<Delegate> clone() const = 0;
    	virtual void operator()() const = 0;
    	virtual bool hasReturn() const = 0;
        virtual void* getReturn() const = 0;
    	virtual ~Delegate();
    protected:
    	Delegate(const Delegate&){}
    	Delegate& operator=(const Delegate&)
    	{ return *this; }
    };
     
    Delegate::~Delegate(){}
     
    template<class... ArgT>
    struct FastDelegateImpl : Delegate {
    	template<class F, class... ArgU>
    	FastDelegateImpl(F&& f, ArgU&&... arg)
    		: func(std::forward<F>(f))
    		, param(std::forward<ArgU>(arg)...)
    	{}
    	std::unique_ptr<Delegate> clone() const
    	{ return std::make_unique<FastDelegateImpl>(*this); }
    	void operator()() const
    	{ call(std::make_index_sequence<sizeof...(ArgT)>()); }
    	template<class... ArgU>
    	void setParam(ArgU&&... arg)
    	{ param=std::make_tuple(std::forward<ArgU>(arg)...); }
        bool hasReturn() const {
            return false;
        }
        void* getReturn() const {
            return 0;
        }
    private:
    	template<std::size_t... I>
    	void call(std::index_sequence<I...>) const
    	{ func(std::get<I>(param)...); }
     
    	DynamicFunction<void(ArgT...)> func;
    	std::tuple<ArgT...> param;
    };
    template<class R, class... ArgT>
    struct FastDelegateImpl2 : Delegate {
    	template<class F, class... ArgU>
    	FastDelegateImpl2(F&& f, ArgU&&... arg)
    		: func(std::forward<F>(f))
    		, param(std::forward<ArgU>(arg)...)
    	{}
    	std::unique_ptr<Delegate> clone() const
    	{ return std::make_unique<FastDelegateImpl>(*this); }
    	void operator()() const
    	{ returnValue = reinterpret_cast<void*>(call(std::make_index_sequence<sizeof...(ArgT)>())); }
    	template<class... ArgU>
    	void setParam(ArgU&&... arg)
    	{ param=std::make_tuple(std::forward<ArgU>(arg)...); }
        bool hasReturn() const {
            return true;
        }
        void* getReturn() const {
            return returnValue;
        }
    private:
    	template<std::size_t... I>
    	void call(std::index_sequence<I...>) const
    	{ func(std::get<I>(param)...); }
     
    	DynamicFunction<R(ArgT...)> func;
    	std::tuple<ArgT...> param;
    	void* returnValue;
    };
    template <typename R>
    struct FastDelegate {
        template<class F, class... Arg>
    	FastDelegate(F&& f, Arg&&... arg) :
    		delegate(std::make_unique<FastDelegateImpl2<R, 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
    	{   (*delegate)();
            void* p = delegate->getReturn();
            return *reinterpret_cast<R*> (&p);
        }
    	template<class... Arg>
    	void setParams(Arg&&... arg)
    	{
    		using DynamicType = FastDelegateImpl2<Arg...>*;
     
    		if(dynamic_cast<DynamicType>(delegate.get()))
    			dynamic_cast<DynamicType>(delegate.get())->setParam(std::forward<Arg>(arg)...);
    	}
    	void boo(){}
    	private:
    	std::unique_ptr<Delegate> delegate;
    };
    template <>
    struct FastDelegate <DefaultVoid> {
    	template<class F, class... Arg>
    	FastDelegate(F&& f, Arg&&... arg) :
    		delegate(std::make_unique<FastDelegateImpl<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;
    	void operator()() const
    	{ (*delegate)(); }
    	template<class... Arg>
    	void setParams(Arg&&... arg)
    	{
    		using DynamicType = FastDelegateImpl<Arg...>*;
     
    		if(dynamic_cast<DynamicType>(delegate.get()))
    			dynamic_cast<DynamicType>(delegate.get())->setParam(std::forward<Arg>(arg)...);
    	}
    	void boo(){}
     
    private:
    	std::unique_ptr<Delegate> delegate;

    Il me prend void pour R, dans FastDelegateImpl2. (Donc il choisi la version avec retour même si la fonction n'a pas de retour)

  4. #44
    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
    Essaie de définir le cas particulier (void) comme spécialisation de la template du cas général.
    Il faut dans ce cas que le cas void soit déclaré (et défini, donc) après le cas général.
    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. #45
    Invité
    Invité(e)
    Par défaut
    Ok, je vais essayer ça.

  6. #46
    Invité
    Invité(e)
    Par défaut
    Salut!
    Le fait que je n'ai pas utilisé de wrapper sur un std::function c'est aussi pour cette raison.

    Ce code-ci est très intéressant.

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void bar(const char* str, const char* str2) {
        std::cout<<"bar : "<<str<<" "<<str2<<std::endl;
    }
    int main(int argv, char* argc[]) {
        auto function = std::bind(&bar, "1", _1);
        using T = decltype(std::bind(&bar, "1", _1));
        odfaeg::FastDelegate<void> freeFuncDelegate(function, "1", _1);
        freeFuncDelegate.setParams<T>("2");
        freeFuncDelegate();
    }

    Que se passerait t'il dans le cas ou l'objet passé au delegate n'est pas de type std::function ce qui est le cas ici.

    Bref, je veux pas qu'un bête wrapper sur un std::function mais sur n'importe quel type d'objet "callable".

    Au cas ou par exemple je ne connais pas la valeur d'un paramètre lors de la déclaration du delegate, je n'ai qu'à passer un std::bind est le tout est joué.

  7. #47
    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
    Ce code a surtout aucun sens, pourquoi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    odfaeg::FastDelegate<void> freeFuncDelegate(function, "1", _1);
    ? Ton function est un callable a un seul paramètre, pourquoi tu lui en passes deux, qui plus est avec un placeholder alors que le code actuel ne gère pas les placeholder (comme il ne gère pas les std::ref) ? D'ailleurs pour les gérer (les deux) je n'ai pas encore réfléchie à la question, mais je vois venir un nouveau type-erasure à utiliser comme type dans le tuple (l'aternative étant de retourner un nouvel objet à chaque setParam à priori).

    Dans l'absolue std::bind retourne une instance d'une classe inconnue qui surcharge l'opérateur operator() exactement comme le type d'une lambda. std::function est un type-erasure sur n'importe quel callable, donc ton wrapper gère n'importe quel callable dans l'absolu.

    Le code de retour je ne l'ai pas géré, mais tu l'avais fais sur ton ancien code et tu peux appliquer la même technique (i.e. une spécialisation complète de la classe) ou bien essayer de factorier un peu pour ne pas doubler la taille du code alors qu'il n'y a que quelques éléments qui change (à coup de decltype, declval et enable_if).

  8. #48
    Invité
    Invité(e)
    Par défaut
    Je vais essayer de t'expliquer en fait :

    J'ai rajouté un paramètre à la fonction :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    void bar(const char* str, const char* str2) {
        std::cout<<"bar : "<<str<<" "<<str2<<std::endl;
    }

    Donc elle en a deux maintenant.

    Ensuite si je veux faire ceci dans le main :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main(int argv, char* argc[]) {
         auto function = std::bind(&bar, "1", _1);
         odfaeg::FastDelegate<void> freeFuncDelegate(function, "1", _1);
         fonction(function, freeFuncDelegate);
    }

    Et ceci ailleurs que dans le main (par exemple dans une autre fonction)

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template <typename T>
    void fonction (typename T type, FastDelegate<void> delegate) { 
           delegate.setParams<T>("2");
           delegate();
    }

    std::function ne peut pas enregistrer une fonction avec un placeholder vu que les fonctions avec les placeholders ne sont pas "callable".
    L'idée est de faire un tableau sur pointeurs de fonctions non callable, je vais devoir me débrouiller par contre pour enregistrer le type de std::bind, c'est à dire le type de T dans mon cas. (mais ça pas de soucis j'ai une factory donc j'ai ma petite idée en comparent les types à l'exécution)
    Et je passe les paramètres au delegate avant d'appeler la fonction pour avoir une fonction "callable" et ensuite appeler l'operateur() de std::bind!

    Car le problème de std::bind c'est qu'il n'est pas très modulable. :/

  9. #49
    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
    J'ai très bien compris la première fois et non ca n'a toujours aucun sens d'écrire ce que tu as écris.

    Un placeholder ce n'est pas anodin a traiter, si tu ne fais rien pour et qu'il n'est pas dans un std::bind alors c'est assez peu probable que ca marche. Ensuite function est un foncteur à un paramètre, FastDelegate enregistre un foncteur accompagné de ses paramères dans un tuple, un seul paramètre donc un seul élément à passer. D'où la conclusion : ton code ne veut rien dire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    odfaeg::FastDelegate<void> freeFuncDelegate(function, "1");
    freeFuncDelegate();
    Là ca a du sens.

    Pour ta fonction fonction : le code de setParam est, actuellement, fait pour profiter de la déduction automatique des paramètres template, c'est dans la grande majorité des cas inutile de les indiquer. Ensuite sur le fond, quel est l'intérêt de FastDelegate si tu dois aussi donner function en paramètre ? L'intérêt d'un type-erasure c'est de s'abstraire, partiellement, du type, si tu dois repasser l'objet d'origine pour récupérer le type initial, l'intérêt devient presque nul.

    std::bind tiend parfaitement son rôle, même si aujourd'hui son intérêt est plus limité grâce aux lambda. Je ne vois pas ce que tu veux lui ajouter comme modularité : l'objectif est de fixer partiellement les paramètres d'un foncteur, il y arrive, rien à rajouter. L'objectif final de ta classe, si j'ai bien compris, c'est d'avoir associer un foncteur et ses paramètres de manière à pouvoir les faire varier. A l'heure actuelle tu gères le cas : d'un retour void, en fixant l'ensemble des paramètres, sans passage par référence et en devant indiquer tout les paramètres à fixer en même temps. Ca fait beaucoup de point à travailler pour arriver au résultat final, par contre niveau foncteur accepté, tu peux tout prendre, que ca vienne de std::bind ou d'autre chose grâce à l'utilisation de std::function.

    Si tu veux améliorer ces points, dans l'ordre je dirais :
    1. Prendre en charge le type de retour
    2. Permettre de ne changer qu'un paramètre
    3. Prendre en charge le passage par référence
    4. Prendre en charge les placeholder et une fixation partielle des paramètres

    Le dernier point est probablement le plus difficile et risque de demander un réorganisation d'une partie d'un code. Les deuxième est surment le plus simple à faire.

  10. #50
    Invité
    Invité(e)
    Par défaut
    Ouais ce sont les deux derniers points pour lesquels je sèche. :/

  11. #51
    Invité
    Invité(e)
    Par défaut
    Salut,
    Flob90, je ne sais pas du tout comment ton code arrive à compiler, chez moi, j'ai plein d'undefined reference errors pour le dynamic cast et quand je veux passer des const char* aux fonctions (à la place des int) ça ne compile pas.

  12. #52
    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
    Tu peux donner les erreurs complètes ?

  13. #53
    Invité
    Invité(e)
    Par défaut
    C'est bien ce code là non ?

    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
     
    typedef void DefaultVoid;
    template<class C, class... ArgT>
    struct DynamicWrapper {
    	DynamicWrapper(void (C::*pf)(ArgT...)) : pfunc(pf){}
    	template<class O, class... ArgU>
    	void operator()(O* o, ArgU&&... arg) const
    	{
    		if(dynamic_cast<C*>(o))
    			(dynamic_cast<C*>(o)->*pfunc)(std::forward<ArgU>(arg)...);
    	}
    private:
    	void (C::*pfunc)(ArgT...);
    };
     
    template<class F>
    class DynamicFunction;
     
    template<class... ArgT>
    class DynamicFunction<void(ArgT...)>
    	: std::function<void(ArgT...)>
    {
    	using Base = std::function<void(ArgT...)>;
     
    public:
    	template<class F>
    	DynamicFunction(F&& f) : Base(std::forward<F>(f))
    	{}
    	template<class C, class... ArgU>
    	DynamicFunction(void (C::*pf)(ArgU...))
    		: Base(DynamicWrapper<C,ArgU...>(pf))
    	{}
     
    	using Base::operator();
    };
    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(void (C::*pf)(ArgU...))
    		: Base(DynamicWrapper<C,ArgU...>(pf))
    	{}
     
    	using Base::operator();
    };
     
    struct Delegate {
    	Delegate(){}
    	virtual std::unique_ptr<Delegate> clone() const = 0;
    	virtual void operator()();
    	virtual bool hasReturn() const = 0;
        virtual void* getReturn() const = 0;
    	virtual ~Delegate() {}
    protected:
    	Delegate(const Delegate&){}
    	Delegate& operator=(const Delegate&)
    	{ return *this; }
    };
     
     
    template<class... ArgT>
    struct FastDelegateImpl : Delegate {
    	template<class F, class... ArgU>
    	FastDelegateImpl(F&& f, ArgU&&... arg) : Delegate()
    		, func(std::forward<F>(f))
    		, param(std::forward<ArgU>(arg)...)
    	{}
    	std::unique_ptr<Delegate> clone() const
    	{ return std::make_unique<FastDelegateImpl>(*this); }
    	void operator()()
    	{ call(std::make_index_sequence<sizeof...(ArgT)>()); }
    	template<class... ArgU>
    	void setParam(ArgU&&... arg)
    	{ param=std::make_tuple(std::forward<ArgU>(arg)...); }
        bool hasReturn() const {
            return false;
        }
        void* getReturn() const {
            return 0;
        }
    private:
    	template<std::size_t... I>
    	void call(std::index_sequence<I...>) const
    	{ func(std::get<I>(param)...); }
     
    	DynamicFunction<void(ArgT...)> func;
    	std::tuple<ArgT...> param;
    };
    template<class R, class... ArgT>
    struct FastDelegateImpl2 : Delegate {
    	template<class F, class... ArgU>
    	FastDelegateImpl2(F&& f, ArgU&&... arg)
    		: func(std::forward<F>(f))
    		, param(std::forward<ArgU>(arg)...)
    	{}
    	std::unique_ptr<Delegate> clone() const
    	{ return std::make_unique<FastDelegateImpl2>(*this); }
    	void operator()()
    	{ returnValue = reinterpret_cast<void*>(call(std::make_index_sequence<sizeof...(ArgT)>())); }
    	template<class... ArgU>
    	void setParam(ArgU&&... arg)
    	{ param=std::make_tuple(std::forward<ArgU>(arg)...); }
        bool hasReturn() const {
            return true;
        }
        void* getReturn() const {
            return returnValue;
        }
    private:
    	template<std::size_t... I>
    	R call(std::index_sequence<I...>)
    	{ return func(std::get<I>(param)...); }
     
    	DynamicFunction<R(ArgT...)> func;
    	std::tuple<ArgT...> param;
    	void* returnValue;
    };
    template <typename R>
    struct FastDelegate {
        template<class F, class... Arg>
    	FastDelegate(F&& f, Arg&&... arg) :
    		delegate(std::make_unique<FastDelegateImpl2<R, 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
    	{   (*delegate)();
            void* p = delegate->getReturn();
            return *reinterpret_cast<R*> (&p);
        }
    	template<class... Arg>
    	void setParams(Arg&&... arg)
    	{
    		using DynamicType = FastDelegateImpl2<Arg...>*;
     
    		if(dynamic_cast<DynamicType>(delegate.get()))
    			dynamic_cast<DynamicType>(delegate.get())->setParam(std::forward<Arg>(arg)...);
    	}
    	void boo(){}
    	private:
    	std::unique_ptr<Delegate> delegate;
    };
    template <>
    struct FastDelegate <DefaultVoid> {
    	template<class F, class... Arg>
    	FastDelegate(F&& f, Arg&&... arg) :
    		delegate(std::make_unique<FastDelegateImpl<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;
    	void operator()() const
    	{ (*delegate)(); }
    	template<class... Arg>
    	void setParams(Arg&&... arg)
    	{
    		using DynamicType = FastDelegateImpl<Arg...>*;
     
    		if(dynamic_cast<DynamicType>(delegate.get()))
    			dynamic_cast<DynamicType>(delegate.get())->setParam(std::forward<Arg>(arg)...);
    	}
    	void boo(){}
     
    private:
    	std::unique_ptr<Delegate> delegate;
    };

    J'ai juste rajouté la spécialisation pour les fonctions avec type de retour.

    Bref voici les erreurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp||In function ‘int main(int, char**)’:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|525|référence indéfinie vers « vtable for odfaeg::Delegate »|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|530|référence indéfinie vers « vtable for odfaeg::Delegate »|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|532|référence indéfinie vers « vtable for odfaeg::Delegate »|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|651|référence indéfinie vers « typeinfo for odfaeg::Delegate »|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|652|référence indéfinie vers « typeinfo for odfaeg::Delegate »|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|651|référence indéfinie vers « typeinfo for odfaeg::Delegate »|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|652|référence indéfinie vers « typeinfo for odfaeg::Delegate »|
    ||=== Build failed: 7 error(s), 1 warning(s) (0 minute(s), 1 second(s)) ===|
    Et le main :

    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
     
    class Bar {
        public :
        void foo (int str) {
            std::cout<<"foo : "<<str<<std::endl;
        }
        int rfoo(int str) {
            std::cout<<"bar : "<<str<<std::endl;
            return 10;
        }
        virtual ~Bar() {
        }   
    };
    void bar(int str) {
        std::cout<<"bar : "<<str<<std::endl;
    }
    int rbar(int str) {
        std::cout<<"bar : "<<str<<std::endl;
        return 10;
    }
    int main(int argv, char* argc[]) {
        odfaeg::FastDelegate<void> freeFuncDelegate(&bar, 1);
        freeFuncDelegate.setParams(2);
        freeFuncDelegate();
        Bar b;
        Bar* f = new Foo();
        odfaeg::FastDelegate<void> memberFuncDelegate(&Bar::foo, &b, 3);
        memberFuncDelegate.setParams(&b, 4);
        memberFuncDelegate();
        odfaeg::FastDelegate<void> anonymousFunction([](int arg){std::cout<<"anonymous : "<<arg<<std::endl;}, 5);
        anonymousFunction.setParams(6);
        anonymousFunction();
        odfaeg::FastDelegate<int> rfreeFuncDelegate(&rbar, 7);
        odfaeg::FastDelegate<int> rmemberFuncDelegate(&Bar::rfoo, &b, 8);
        const int r1 = rfreeFuncDelegate();
        std::cout<<"r1 : "<<r1<<std::endl;
        const int r2 = rmemberFuncDelegate();
        std::cout<<"r2 : "<<r2<<std::endl;
        return 0;
    }

    J'ai bien mit le code dans un projet à part.

  14. #54
    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
    Avant de rajouter et modifier ce que j'ai écrit, as-tu essayé en copiant/collant simplement le code ?
    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
     
    namespace odfaeg {
     
    template<class C, class... ArgT>
    struct DynamicWrapper {
    	DynamicWrapper(void (C::*pf)(ArgT...)) : pfunc(pf){}
    	template<class O, class... ArgU>
    	void operator()(O* o, ArgU&&... arg) const
    	{
    		if(dynamic_cast<C*>(o))
    			(dynamic_cast<C*>(o)->*pfunc)(std::forward<ArgU>(arg)...);
    	}
    private:
    	void (C::*pfunc)(ArgT...);
    };
     
    template<class F>
    class DynamicFunction;
     
    template<class... ArgT>
    class DynamicFunction<void(ArgT...)>
    	: std::function<void(ArgT...)>
    {
    	using Base = std::function<void(ArgT...)>;
     
    public:
    	template<class F>
    	DynamicFunction(F&& f) : Base(std::forward<F>(f))
    	{}
    	template<class C, class... ArgU>
    	DynamicFunction(void (C::*pf)(ArgU...))
    		: Base(DynamicWrapper<C,ArgU...>(pf))
    	{}
     
    	using Base::operator();
    };
     
    struct Delegate {
    	Delegate() =default;
    	virtual std::unique_ptr<Delegate> clone() const = 0;
    	virtual void operator()() const = 0;
    	virtual ~Delegate();
    protected:
    	Delegate(const Delegate&){}
    	Delegate& operator=(const Delegate&)
    	{ return *this; }
    };
     
    Delegate::~Delegate(){}
     
    template<class... ArgT>
    struct FastDelegateImpl : Delegate {
    	template<class F, class... ArgU>
    	FastDelegateImpl(F&& f, ArgU&&... arg)
    		: func(std::forward<F>(f))
    		, param(std::forward<ArgU>(arg)...)
    	{}
    	std::unique_ptr<Delegate> clone() const
    	{ return std::make_unique<FastDelegateImpl>(*this); }
    	void operator()() const
    	{ call(std::make_index_sequence<sizeof...(ArgT)>()); }
    	template<class... ArgU>
    	void setParam(ArgU&&... arg)
    	{ param=std::make_tuple(std::forward<ArgU>(arg)...); }
     
    private:
    	template<std::size_t... I>
    	void call(std::index_sequence<I...>) const
    	{ func(std::get<I>(param)...); }
     
    	DynamicFunction<void(ArgT...)> func;
    	std::tuple<ArgT...> param;
    };
     
    struct FastDelegate {
    	template<class F, class... Arg>
    	FastDelegate(F&& f, Arg&&... arg) :
    		delegate(std::make_unique<FastDelegateImpl<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;
    	void operator()() const
    	{ (*delegate)(); }
    	template<class... Arg>
    	void setParam(Arg&&... arg)
    	{
    		using DynamicType = FastDelegateImpl<Arg...>*;
     
    		if(dynamic_cast<DynamicType>(delegate.get()))
    			dynamic_cast<DynamicType>(delegate.get())->setParam(std::forward<Arg>(arg)...);
    	}
    	void boo(){}
     
    private:
    	std::unique_ptr<Delegate> delegate;
    };
     
    }
     
    void foo(int i, int j)
    { std::cout << i << j; }
     
    struct A {
    	void bar(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; }
     
    int main(){
    	odfaeg::FastDelegate f1(foo,3,4);
    	f1();
    	f1.setParam(5,6);
    	f1();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate f2(
    		[](int i, int j){ std::cout << i << j; },
    		7,8
    	);
    	f2();
    	f2.setParam(9,10);
    	f2();
    	std::cout << std::endl;
     
    	int i = 11;
    	odfaeg::FastDelegate f3(
    		[i](int j){ std::cout << i << j; },
    		12
    	);
    	f3();
    	f3.setParam(13);
    	f3();
    	std::cout << std::endl;
     
    	A a;
    	odfaeg::FastDelegate f4(&A::bar,&a,14);
    	f4();
    	f4.setParam(&a,15);
    	f4();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate f5 = f1;
    	f5();
    	f5=f3;
    	f5();
    	std::cout << std::endl;
     
    	C c;
    	B* b = &c;
    	odfaeg::FastDelegate f6(&C::foo,b);
    	f6();
    	f6.setParam(&c);
    	f6();
    	std::cout << std::endl;
    }
    Les fonctions définient à l'extérieur du corps de la classe c'est pas anodin.

    PS: Il manque juste les include.

  15. #55
    Invité
    Invité(e)
    Par défaut
    Il manque D dans ton code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|69|error: ‘D’ was not declared in this scope|

  16. #56
    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
    Voila, code édité, plus besoin de D. (C'était le dernier exemple que j'avais ajouter en éditant le message où il y a le code, il est pas particulièrement pertinant).

  17. #57
    Invité
    Invité(e)
    Par défaut
    Bon j'ai commenté celui qui utilise la classe D, et ça compile et ça s'exécute sans problème, maintenant, il faut que je voie comment faire ça pour le types de retour.

    Ha oui tu défini le destructeur virtuel en dehors de la classe c'est pour ça.

    Sinon ça ne marche qu'avec des int, ça ne fonctionne pas avec des std::string. (Ni des const char*)

    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
     
    ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===|
    /usr/include/c++/4.9/tuple||In instantiation of ‘std::_Tuple_impl<_Idx, _Head, _Tail ...>& std::_Tuple_impl<_Idx, _Head, _Tail ...>::operator=(std::_Tuple_impl<_Idx, _UHead, _UTails ...>&&) [with _UHead = const char*; _UTails = {const char*}; long unsigned int _Idx = 0ul; _Head = const char (&)[2]; _Tail = {const char (&)[2]}]’:|
    /usr/include/c++/4.9/tuple|642|required from ‘std::tuple<_T1, _T2>& std::tuple<_T1, _T2>::operator=(std::tuple<_U1, _U2>&&) [with _U1 = const char*; _U2 = const char*; _T1 = const char (&)[2]; _T2 = const char (&)[2]]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|532|required from ‘void odfaeg::FastDelegateImpl<ArgT>::setParam(ArgU&& ...) [with ArgU = {const char (&)[2], const char (&)[2]}; ArgT = {const char (&)[2], const char (&)[2]}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|566|required from ‘void odfaeg::FastDelegate::setParam(Arg&& ...) [with Arg = {const char (&)[2], const char (&)[2]}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|25|required from here|
    /usr/include/c++/4.9/tuple|366|error: assignment of read-only location ‘std::_Tuple_impl<_Idx, _Head, _Tail ...>::_M_head<0ul, const char (&)[2], {const char (&)[2]}>((*(std::_Tuple_impl<0ul, const char (&)[2], const char (&)[2]>*)this))’|
    /usr/include/c++/4.9/tuple|366|error: incompatible types in assignment of ‘const char*’ to ‘const char [2]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h||In instantiation of ‘odfaeg::DynamicFunction<void(ArgT ...)>::DynamicFunction(F&&) [with F = main()::<lambda(std::string&, std::string&)>; ArgT = {const char (&)[2], const char (&)[2]}]’:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|524|required from ‘odfaeg::FastDelegateImpl<ArgT>::FastDelegateImpl(F&&, ArgU&& ...) [with F = main()::<lambda(std::string&, std::string&)>; ArgU = {const char (&)[2], const char (&)[2]}; ArgT = {const char (&)[2], const char (&)[2]}]’|
    /usr/include/c++/4.9/bits/unique_ptr.h|762|required from ‘typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = odfaeg::FastDelegateImpl<const char (&)[2], const char (&)[2]>; _Args = {main()::<lambda(std::string&, std::string&)>, const char (&)[2], const char (&)[2]}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<odfaeg::FastDelegateImpl<const char (&)[2], const char (&)[2]>, std::default_delete<odfaeg::FastDelegateImpl<const char (&)[2], const char (&)[2]> > >]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|547|required from ‘odfaeg::FastDelegate::FastDelegate(F&&, Arg&& ...) [with F = main()::<lambda(std::string&, std::string&)>; Arg = {const char (&)[2], const char (&)[2]}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|32|required from here|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|496|error: no matching function for call to ‘std::function<void(const char (&)[2], const char (&)[2])>::function(main()::<lambda(std::string&, std::string&)>)’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|496|note: candidates are:|
    /usr/include/c++/4.9/functional|2226|note: template<class _Functor, class> std::function<_Res(_ArgTypes ...)>::function(_Functor)|
    /usr/include/c++/4.9/functional|2226|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/functional|2201|note: std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = void; _ArgTypes = {const char (&)[2], const char (&)[2]}]|
    /usr/include/c++/4.9/functional|2201|note:   no known conversion for argument 1 from ‘main()::<lambda(std::string&, std::string&)>’ to ‘std::function<void(const char (&)[2], const char (&)[2])>&&’|
    /usr/include/c++/4.9/functional|2404|note: std::function<_Res(_ArgTypes ...)>::function(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {const char (&)[2], const char (&)[2]}]|
    /usr/include/c++/4.9/functional|2404|note:   no known conversion for argument 1 from ‘main()::<lambda(std::string&, std::string&)>’ to ‘const std::function<void(const char (&)[2], const char (&)[2])>&’|
    /usr/include/c++/4.9/functional|2181|note: std::function<_Res(_ArgTypes ...)>::function(std::nullptr_t) [with _Res = void; _ArgTypes = {const char (&)[2], const char (&)[2]}; std::nullptr_t = std::nullptr_t]|
    /usr/include/c++/4.9/functional|2181|note:   no known conversion for argument 1 from ‘main()::<lambda(std::string&, std::string&)>’ to ‘std::nullptr_t’|
    /usr/include/c++/4.9/functional|2174|note: std::function<_Res(_ArgTypes ...)>::function() [with _Res = void; _ArgTypes = {const char (&)[2], const char (&)[2]}]|
    /usr/include/c++/4.9/functional|2174|note:   candidate expects 0 arguments, 1 provided|
    /usr/include/c++/4.9/tuple||In instantiation of ‘std::_Tuple_impl<_Idx, _Head, _Tail ...>& std::_Tuple_impl<_Idx, _Head, _Tail ...>::operator=(std::_Tuple_impl<_Idx, _UHead, _UTails ...>&&) [with _UHead = const char*; _UTails = {const char*}; long unsigned int _Idx = 0ul; _Head = const char (&)[2]; _Tail = {const char (&)[3]}]’:|
    /usr/include/c++/4.9/tuple|642|required from ‘std::tuple<_T1, _T2>& std::tuple<_T1, _T2>::operator=(std::tuple<_U1, _U2>&&) [with _U1 = const char*; _U2 = const char*; _T1 = const char (&)[2]; _T2 = const char (&)[3]]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|532|required from ‘void odfaeg::FastDelegateImpl<ArgT>::setParam(ArgU&& ...) [with ArgU = {const char (&)[2], const char (&)[3]}; ArgT = {const char (&)[2], const char (&)[3]}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|566|required from ‘void odfaeg::FastDelegate::setParam(Arg&& ...) [with Arg = {const char (&)[2], const char (&)[3]}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|34|required from here|
    /usr/include/c++/4.9/tuple|366|error: assignment of read-only location ‘std::_Tuple_impl<_Idx, _Head, _Tail ...>::_M_head<0ul, const char (&)[2], {const char (&)[3]}>((*(std::_Tuple_impl<0ul, const char (&)[2], const char (&)[3]>*)this))’|
    /usr/include/c++/4.9/tuple|366|error: incompatible types in assignment of ‘const char*’ to ‘const char [2]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h||In instantiation of ‘odfaeg::DynamicFunction<void(ArgT ...)>::DynamicFunction(F&&) [with F = main()::<lambda(int)>; ArgT = {const char (&)[3]}]’:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|524|required from ‘odfaeg::FastDelegateImpl<ArgT>::FastDelegateImpl(F&&, ArgU&& ...) [with F = main()::<lambda(int)>; ArgU = {const char (&)[3]}; ArgT = {const char (&)[3]}]’|
    /usr/include/c++/4.9/bits/unique_ptr.h|762|required from ‘typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = odfaeg::FastDelegateImpl<const char (&)[3]>; _Args = {main()::<lambda(int)>, const char (&)[3]}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<odfaeg::FastDelegateImpl<const char (&)[3]>, std::default_delete<odfaeg::FastDelegateImpl<const char (&)[3]> > >]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|547|required from ‘odfaeg::FastDelegate::FastDelegate(F&&, Arg&& ...) [with F = main()::<lambda(int)>; Arg = {const char (&)[3]}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|42|required from here|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|496|error: no matching function for call to ‘std::function<void(const char (&)[3])>::function(main()::<lambda(int)>)’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|496|note: candidates are:|
    /usr/include/c++/4.9/functional|2226|note: template<class _Functor, class> std::function<_Res(_ArgTypes ...)>::function(_Functor)|
    /usr/include/c++/4.9/functional|2226|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/functional|2201|note: std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = void; _ArgTypes = {const char (&)[3]}]|
    /usr/include/c++/4.9/functional|2201|note:   no known conversion for argument 1 from ‘main()::<lambda(int)>’ to ‘std::function<void(const char (&)[3])>&&’|
    /usr/include/c++/4.9/functional|2404|note: std::function<_Res(_ArgTypes ...)>::function(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {const char (&)[3]}]|
    /usr/include/c++/4.9/functional|2404|note:   no known conversion for argument 1 from ‘main()::<lambda(int)>’ to ‘const std::function<void(const char (&)[3])>&’|
    /usr/include/c++/4.9/functional|2181|note: std::function<_Res(_ArgTypes ...)>::function(std::nullptr_t) [with _Res = void; _ArgTypes = {const char (&)[3]}; std::nullptr_t = std::nullptr_t]|
    /usr/include/c++/4.9/functional|2181|note:   no known conversion for argument 1 from ‘main()::<lambda(int)>’ to ‘std::nullptr_t’|
    /usr/include/c++/4.9/functional|2174|note: std::function<_Res(_ArgTypes ...)>::function() [with _Res = void; _ArgTypes = {const char (&)[3]}]|
    /usr/include/c++/4.9/functional|2174|note:   candidate expects 0 arguments, 1 provided|
    /usr/include/c++/4.9/tuple||In instantiation of ‘std::_Tuple_impl<_Idx, _Head, _Tail ...>& std::_Tuple_impl<_Idx, _Head, _Tail ...>::operator=(std::_Tuple_impl<_Idx, _UHead, _UTails ...>&&) [with _UHead = const char*; _UTails = {}; long unsigned int _Idx = 0ul; _Head = const char (&)[3]; _Tail = {}]’:|
    /usr/include/c++/4.9/tuple|500|required from ‘std::tuple< <template-parameter-1-1> >& std::tuple< <template-parameter-1-1> >::operator=(std::tuple<_Args1 ...>&&) [with _UElements = {const char*}; <template-parameter-2-2> = void; _Elements = {const char (&)[3]}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|532|required from ‘void odfaeg::FastDelegateImpl<ArgT>::setParam(ArgU&& ...) [with ArgU = {const char (&)[3]}; ArgT = {const char (&)[3]}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/delegate.h|566|required from ‘void odfaeg::FastDelegate::setParam(Arg&& ...) [with Arg = {const char (&)[3]}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|44|required from here|
    /usr/include/c++/4.9/tuple|366|error: assignment of read-only location ‘std::_Tuple_impl<_Idx, _Head, _Tail ...>::_M_head<0ul, const char (&)[3], {}>((*(std::_Tuple_impl<0ul, const char (&)[3]>*)this))’|
    /usr/include/c++/4.9/tuple|366|error: incompatible types in assignment of ‘const char*’ to ‘const char [3]’|
    ||=== Build failed: 8 error(s), 25 warning(s) (0 minute(s), 0 second(s)) ===|
    PS : hors que ma version fonctionne avec les const char*.
    Dernière modification par Invité ; 05/09/2014 à 14h02.

  18. #58
    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
    D'accord, là c'est un vrai problème. On doit pouvoir le résoudre en parti avec une decay conversion où il faut (je suis pas chez moi, je peux pas me plonger assez dans le code pour te dire où exactement). En attendant tu peux déjà avancer sur les autres problématique avec cette base.

    Edit: Quand tu postes une erreur, c'est mieux avec le code correspondant quand même.

  19. #59
    Invité
    Invité(e)
    Par défaut
    Je ne peux pas trop dire ou non plus au niveau du std::decay.

    Je m'y connais très peu en c++11 et la méta-programmation me cassais tellement le crâne à certains moment que comme tu as pu le voir j'ai fais une solution à l'ancienne sans passer par un std::function, ni par des std::decay, des std::forward et tout le bazard. (A cause justement de tout ses problèmes)

    Et encore, ma solution ne fonctionne pas avec les références.

  20. #60
    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
    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<functional>
    #include<memory>
    #include<tuple>
    #include<type_traits>
    #include<utility>
     
    #include<boost/mpl/apply.hpp>
    #include<boost/mpl/if.hpp>
    #include<boost/mpl/placeholders.hpp>
     
    namespace mpl = boost::mpl;
     
    using mpl::placeholders::_;
     
    namespace odfaeg {
     
    template<class C, class R, 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<C,R,ArgU...>(pf))
    	{}
     
    	using Base::operator();
    };
     
    template<class R>
    struct Delegate {
    	Delegate() =default;
    	virtual std::unique_ptr<Delegate> clone() const = 0;
    	virtual R operator()() const = 0;
    	virtual ~Delegate(){}
    protected:
    	Delegate(const Delegate&){}
    	Delegate& operator=(const Delegate&)
    	{ return *this; }
    };
     
    template<class PFun, class PConv, 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()() const
    	{ return call(std::make_index_sequence<sizeof...(ArgT)>()); }
    	template<class... ArgU>
    	void setParam(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)...); }
     
    	typename mpl::apply<
    		PFun,R(typename mpl::apply<PConv,ArgT>::type...)
    	>::type func;
    	std::tuple<typename mpl::apply<PConv,ArgT>::type...> param;
    };
     
    template<
    	class R,
    	class PFun =DynamicFunction<_>,
    	class PConv =mpl::if_<std::is_same<std::decay<_>,const char*>,std::string,std::decay<_>>
    >
    struct FastDelegate {
    	template<class F, class... Arg>
    	FastDelegate(F&& f, Arg&&... arg) :
    		delegate(std::make_unique<FastDelegateImpl<PFun,PConv,R,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 setParam(Arg&&... arg)
    	{
    		using DynamicType = FastDelegateImpl<PFun,PConv,R,Arg...>*;
     
    		if(dynamic_cast<DynamicType>(delegate.get()))
    			dynamic_cast<DynamicType>(delegate.get())->setParam(std::forward<Arg>(arg)...);
    	}
     
    private:
    	std::unique_ptr<Delegate<R>> delegate;
    };
     
    }
    Utilisation :
    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
     
    #include<iostream>
    #include<string>
     
    using namespace std::literals;
     
    void foo(int i, int j)
    { std::cout << i << j; }
     
    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; }
     
    int main(){
    	odfaeg::FastDelegate<void> f1(foo,3,4);
    	f1();
    	f1.setParam(5,6);
    	f1();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate<void> f2(
    		[](int i, int j){ std::cout << i << j; },
    		7,8
    	);
    	f2();
    	f2.setParam(9,10);
    	f2();
    	std::cout << std::endl;
     
    	int i = 11;
    	odfaeg::FastDelegate<void> f3(
    		[i](int j){ std::cout << i << j; },
    		12
    	);
    	f3();
    	f3.setParam(13);
    	f3();
    	std::cout << std::endl;
     
    	A a;
    	odfaeg::FastDelegate<void> f4(&A::foo,&a,14);
    	f4();
    	f4.setParam(&a,15);
    	f4();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate<void> f5 = f1;
    	f5();
    	f5=f3;
    	f5();
    	std::cout << std::endl;
     
    	C c;
    	B* b = &c;
    	odfaeg::FastDelegate<void> f6(&C::foo,b);
    	f6();
    	f6.setParam(&c);
    	f6();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate<void> f7(D(),16);
    	f7();
    	f7.setParam(17);
    	f7();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate<void> f8(bar,"ab"s);
    	f8();
    	f8.setParam("abc"s);
    	f8();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate<void> f9(bar,"de");
    	f9();
    	f9.setParam("def");
    	f9();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate<int> f10(goo,18);
    	std::cout << f10();
    	f10.setParam(19);
    	std::cout << f10();
    	std::cout << std::endl;
    }
    Code de retour, classe de politique (nécessite boost.mpl) et std::string dans une certaine mesure. Gérer les cas comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void foo(const char*);
    C'est assez complexe car ton tuple ne doit pas stocker de const char* qui risque de créer des fuite mémoire mais des std::string, ça mon code le fait (mais uniquement pour std::string pas les autre basic_string), par contre ça veut dire qu'il faut explicitement repasser sur du const char* à l'appel, ça peut se faire mais c'est pas trivial. De toute manière tu es sensé utiliser std::string et "abc"s maintenant en C++.

    J'ai commencé à regarder la gestion des références, mais pour le moment je me retrouve à partir sur une piste à base de std::unique_ptr<void> qui me plait assez peu. L'objectif (avec cette piste ou une autre) c'est de changer les types du tuple pour des types plus généraux qui peuvent convenir à tout ce qui peut être converti vers le type du foncteur et à std::reference_wrapper ce qui fait un paquet de monde, d'où la piste du std::unique_ptr<void>. Sachant que ca devra se raffiner en "plein de type sauf les types placeholder pour pouvoir les gérer".

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

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