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 :

Comment passer des références à un tuple ?


Sujet :

Langage C++

  1. #21
    Invité
    Invité(e)
    Par défaut
    Mwai il semblerait qu'il n'y ai pas vraiment moyen de le faire pas référence, un type A me déduis un passage par valeur si c'est une valeur ou une référence sur une valeur, un type A&& me déduis un passage par référence pour tout, et dans ce cas là, ça ne fonctionne plus du tout.
    J'ai des erreurs du genre invalid initialization of reference from a value pour les référence, et pour le passage par pointeur et par valeur j'ai aussi des erreurs.

    La seule chose qui fonctionne est quand je déclare A en passant pas de référence.

  2. #22
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    En fait, tu ne peux pas mélanger valeurs et références dans les arguments d'un template variadique.

    Tu as le choix entre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    // 1. 
    template <typename ...Args>
    FastDelegate(void(*f)(Args...), Args... args); // tous les args sont des valeurs
     
    // 2.
    template <typename ...Args>
    FastDelegate(void(*f)(Args&...), Args&... args); // tous les args sont des références
    Les paramètres ne sont correctement déduits que si tous les paramètres de la fonction que tu donnes au constructeur correspondent, cad s'ils sont tous de type valeur ou de type référence

  3. #23
    Invité
    Invité(e)
    Par défaut
    Mwai je pense que je ne vais utiliser que des valeurs alors (ou bien des pointeurs) pour mes fonctions de callback.

    Ce sera beaucoup plus simple!

    Parce que je ne peux pas utiliser les deux (pointeurs et références) à cause de la déduction. (Ce qui justement fait la force d'un "type erasure")

  4. #24
    Invité
    Invité(e)
    Par défaut
    Ca y est, j'ai trouvé!

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template <class O, typename ...A> FastDelegate(void(O::*f)(A...), O* object, A... args) {
        delegate = new FastDelegate2<O, A...>(f, object, args...);
    }
    template <class O, typename ...A, class = typename std::enable_if<std::is_reference<A...>::value>::type> FastDelegate(void(O::*f)(A...), O* object, A&&... args) {
        //code à appliqué si a est une référence.
    }

    Même pas besoin de std::ref.

    Par contre je pense que je dois faire ça si je veux vraiment avoir un passage par référence sinon il va me choisir le passage par valeur :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     std::ofstream ofs("FichierDeSerialisation");
    	odfaeg::OTextArchive oa(ofs);
            odfaeg::OTextArchive roa& = oa;
    	B b;
    	test::FastDelegate<void> f1(&B::vtserialize,&b,roa);

    Mais personnellement c'est pas vraiment un problème.

    Je pense que je vais appliquer cette solution avec l'algorithme de flob90 ainsi il me déduira correctement les types des arguments des pointeurs sur les fonctions même si elles sont template et tout les problèmes seront résolu à part celui avec les placeholders, pour cela voir mon autre sujet.

    Par contre je ne sais pas si ça va marcher si par exemple les arguments passé au pointeur sur la fonction template ne sont pas tous des références.

  5. #25
    Invité
    Invité(e)
    Par défaut
    Salut,

    je sais mon code source n'est pas optimal mais c'est la seule solution qui fonctionne dans mon cas avec tout les codes que j'ai testé, pour ceux qui s'impatiente, sachez que je ne vous force pas à répondre.

    Mais je pose la question au cas ou.

    J'ai presque terminé mon système de callback et il fonctionne avec tout les type de fonctions (fonctions avec placeholders, lambdas, fonction membre (avec polymorphisme dynamique et statique) et fonction non membre avec passage des arguments par valeur et par pointeur.)
    Mais pour le passage des arguments par référence avec std::ref, j'ai un peu de mal, j'ai essayer quelque chose de ce goût là: (A l'aide d'un code qu'on m'a proposé)

    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
     
    template<class T>
    struct IRefVal {
    	IRefVal()=default;
    	virtual T& get() =0;
    	virtual std::unique_ptr<IRefVal> 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>(*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* t)
    		: rv(std::make_unique<Pointer<T>>(t))
    	{}
    	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;
    };
     
    template<class T>
    struct ToStoreImpl
    { using type = T; };
     
    template<class T>
    struct ToStoreImpl<std::reference_wrapper<T>>
    { using type = T; };
    template<class T>
    struct ToStoreImpl<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 O, typename ...A> class  FastDelegate2 : public Delegate {
            public :
            FastDelegate2 (void(O::*func)(A...), O* object, A... args)  {
                typedef void(*CB)(MemberFunction<void(O*, A...)>, O*, A...);
                CB cb = &callback;
                funct = new Functor<void(MemberFunction<void(O*, A...)>, O*, A...)> (cb, MemberFunction<void(O*, A...)>(func));
                params = std::make_tuple(object, args...);
            }
            FastDelegate2<O, A...>* getType() {
                return this;
            }
            FastDelegate2 (void(O::*func)(A...) const, O* object, A... args)  {
                typedef void(*CB)(MemberFunction<void(O*, A...)>, O*, A...);
                CB cb = &callback;
                funct = new Functor<void(MemberFunction<void(O*, A...)>,O* , A...)> (cb, MemberFunction<void(O*, A...)>(func), object);
                params = std::make_tuple(object, args...);
            }
            void setParams (O* obj, A... args) {
                params = std::make_tuple (obj, args...);
            }
            void operator()() {
                (*funct)(params);
            }
            bool operator== (Delegate& other) const {
                if (&dynamic_cast<FastDelegate2<O, A...>&>(other) == nullptr) {
                    return false;
                }
                FastDelegate2<O, A...>& delegate2 = dynamic_cast<FastDelegate2<O, A...>&>(other);
                return *funct == *(delegate2.funct);
            }
            bool hasReturn() const {
                return false;
            }
            void* getReturn() const {
                return 0;
            }
            private :
            std::tuple<O*, IRefVal<A>...> params;
            Functor<void(MemberFunction<void(O*, A...)>, O*, A...)> *funct;
     
    };

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template <class O, typename ...A> FastDelegate(void(O::*f)(A...), O* object, A... args) {
            delegate = new FastDelegate2<O, ToStore_t<A>...>(f, object, args...);
     
        }

    Mais, ça ne fonctionne pas. :/


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===|
    /usr/include/c++/4.9/tuple||In instantiation of ‘struct std::_Head_base<1ul, odfaeg::IRefVal<int>, false>’:|
    /usr/include/c++/4.9/tuple|229|  recursively required from ‘struct std::_Tuple_impl<1ul, odfaeg::IRefVal<int> >’|
    /usr/include/c++/4.9/tuple|229|required from ‘struct std::_Tuple_impl<0ul, A*, odfaeg::IRefVal<int> >’|
    /usr/include/c++/4.9/tuple|521|required from ‘class std::tuple<A*, odfaeg::IRefVal<int> >’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|284|required from ‘class odfaeg::FastDelegate2<A, int>’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|432|required from ‘odfaeg::FastDelegate<void>::FastDelegate(void (O::*)(A ...), O*, A ...) [with O = A; A = {int}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|106|required from here|
    /usr/include/c++/4.9/tuple|172|error: cannot declare field ‘std::_Head_base<1ul, odfaeg::IRefVal<int>, false>::_M_head_impl’ to be of abstract type ‘odfaeg::IRefVal<int>’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|13|note:   because the following virtual functions are pure within ‘odfaeg::IRefVal<int>’:|
    /usr/local/include/odfaeg/Core/fastDelegate.h|15|note:     T& odfaeg::IRefVal<T>::get() [with T = int]|
    /usr/local/include/odfaeg/Core/fastDelegate.h|16|note:     std::unique_ptr<odfaeg::IRefVal<T> > odfaeg::IRefVal<T>::clone() const [with T = int]|
    /usr/include/c++/4.9/tuple||In instantiation of ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base() [with long unsigned int _Idx = 0ul; _Head = std::reference_wrapper<int>]’:|
    /usr/include/c++/4.9/tuple|251|required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl() [with long unsigned int _Idx = 0ul; _Head = std::reference_wrapper<int>; _Tail = {}]’|
    /usr/include/c++/4.9/tuple|394|required from ‘constexpr std::tuple< <template-parameter-1-1> >::tuple() [with _Elements = {std::reference_wrapper<int>}]’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|130|required from ‘odfaeg::FastDelegate6<F, A>::FastDelegate6(F, A ...) [with F = void (*)(int&); A = {std::reference_wrapper<int>}]’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|439|required from ‘odfaeg::FastDelegate<void>::FastDelegate(F, A ...) [with F = void (*)(int&); A = {std::reference_wrapper<int>}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|150|required from here|
    /usr/include/c++/4.9/tuple|131|error: no matching function for call to ‘std::reference_wrapper<int>::reference_wrapper()’|
    /usr/include/c++/4.9/tuple|131|note: candidates are:|
    /usr/include/c++/4.9/functional|413|note: std::reference_wrapper<_Tp>::reference_wrapper(const std::reference_wrapper<_Tp>&) [with _Tp = int]|
    /usr/include/c++/4.9/functional|413|note:   candidate expects 1 argument, 0 provided|
    /usr/include/c++/4.9/functional|407|note: std::reference_wrapper<_Tp>::reference_wrapper(_Tp&) [with _Tp = int]|
    /usr/include/c++/4.9/functional|407|note:   candidate expects 1 argument, 0 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 = int; _UTails = {}; long unsigned int _Idx = 1ul; _Head = odfaeg::IRefVal<int>; _Tail = {}]’:|
    /usr/include/c++/4.9/tuple|368|required from ‘std::_Tuple_impl<_Idx, _Head, _Tail ...>& std::_Tuple_impl<_Idx, _Head, _Tail ...>::operator=(std::_Tuple_impl<_Idx, _UHead, _UTails ...>&&) [with _UHead = A*; _UTails = {int}; long unsigned int _Idx = 0ul; _Head = A*; _Tail = {odfaeg::IRefVal<int>}]’|
    /usr/include/c++/4.9/tuple|642|required from ‘std::tuple<_T1, _T2>& std::tuple<_T1, _T2>::operator=(std::tuple<_U1, _U2>&&) [with _U1 = A*; _U2 = int; _T1 = A*; _T2 = odfaeg::IRefVal<int>]’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|265|required from ‘void odfaeg::FastDelegate2<O, A>::setParams(O*, A ...) [with O = A; A = {int}]’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|452|required from ‘void odfaeg::FastDelegate<void>::setParams(O*, A ...) [with O = A; <template-parameter-1-2> = void; A = {int}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|108|required from here|
    /usr/include/c++/4.9/tuple|366|error: no match foroperator=’ (operand types are ‘odfaeg::IRefVal<int>’ andint)|
    /usr/include/c++/4.9/tuple|366|note: candidate is:|
    /usr/local/include/odfaeg/Core/fastDelegate.h|21|note: odfaeg::IRefVal<T>& odfaeg::IRefVal<T>::operator=(const odfaeg::IRefVal<T>&) [with T = int]|
    /usr/local/include/odfaeg/Core/fastDelegate.h|21|note:   no known conversion for argument 1 from ‘int’ to ‘const odfaeg::IRefVal<int>&’|
    /usr/include/c++/4.9/tuple||In instantiation of ‘struct std::_Head_base<1ul, odfaeg::IRefVal<odfaeg::OTextArchive*>, false>’:|
    /usr/include/c++/4.9/tuple|229|  recursively required from ‘struct std::_Tuple_impl<1ul, odfaeg::IRefVal<odfaeg::OTextArchive*> >’|
    /usr/include/c++/4.9/tuple|229|required from ‘struct std::_Tuple_impl<0ul, B*, odfaeg::IRefVal<odfaeg::OTextArchive*> >’|
    /usr/include/c++/4.9/tuple|521|required from ‘class std::tuple<B*, odfaeg::IRefVal<odfaeg::OTextArchive*> >’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|284|required from ‘class odfaeg::FastDelegate2<B, odfaeg::OTextArchive*>’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|452|required from ‘void odfaeg::FastDelegate<void>::setParams(O*, A ...) [with O = B; <template-parameter-1-2> = void; A = {odfaeg::OTextArchive*}]’|
    /usr/local/include/odfaeg/Core/serialization.h|58|required from ‘static void odfaeg::BaseFact<B>::callFunction(std::string, std::string, std::string, A ...) [with A = {B*, odfaeg::OTextArchive*}; B = B; std::string = std::basic_string<char>]’|
    /usr/local/include/odfaeg/Core/serialization.h|96|required from ‘void odfaeg::Serializer<B>::serialize(std::string, std::string, Archive*) [with Archive = odfaeg::OTextArchive; B = B; std::string = std::basic_string<char>]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|41|required from ‘void B::BKEY::serialize_object(std::string, std::string, Archive*) [with Archive = odfaeg::OTextArchive; std::string = std::basic_string<char>]’|
    /usr/local/include/odfaeg/Core/archive.h|204|required from ‘void odfaeg::OTextArchive::operator()(O*, D ...) [with O = B; D = {}; <template-parameter-1-3> = void; <template-parameter-1-4> = void; <template-parameter-1-5> = void; <template-parameter-1-6> = void]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|158|required from here|
    /usr/include/c++/4.9/tuple|172|error: cannot declare field ‘std::_Head_base<1ul, odfaeg::IRefVal<odfaeg::OTextArchive*>, false>::_M_head_impl’ to be of abstract type ‘odfaeg::IRefVal<odfaeg::OTextArchive*>’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|13|note:   because the following virtual functions are pure within ‘odfaeg::IRefVal<odfaeg::OTextArchive*>’:|
    /usr/local/include/odfaeg/Core/fastDelegate.h|15|note:     T& odfaeg::IRefVal<T>::get() [with T = odfaeg::OTextArchive*]|
    /usr/local/include/odfaeg/Core/fastDelegate.h|16|note:     std::unique_ptr<odfaeg::IRefVal<T> > odfaeg::IRefVal<T>::clone() const [with T = odfaeg::OTextArchive*]|
    /usr/include/c++/4.9/tuple||In instantiation of ‘struct std::_Head_base<1ul, odfaeg::IRefVal<odfaeg::ITextArchive*>, false>’:|
    /usr/include/c++/4.9/tuple|229|  recursively required from ‘struct std::_Tuple_impl<1ul, odfaeg::IRefVal<odfaeg::ITextArchive*> >’|
    /usr/include/c++/4.9/tuple|229|required from ‘struct std::_Tuple_impl<0ul, B*, odfaeg::IRefVal<odfaeg::ITextArchive*> >’|
    /usr/include/c++/4.9/tuple|521|required from ‘class std::tuple<B*, odfaeg::IRefVal<odfaeg::ITextArchive*> >’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|284|required from ‘class odfaeg::FastDelegate2<B, odfaeg::ITextArchive*>’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|452|required from ‘void odfaeg::FastDelegate<void>::setParams(O*, A ...) [with O = B; <template-parameter-1-2> = void; A = {odfaeg::ITextArchive*}]’|
    /usr/local/include/odfaeg/Core/serialization.h|58|required from ‘static void odfaeg::BaseFact<B>::callFunction(std::string, std::string, std::string, A ...) [with A = {B*, odfaeg::ITextArchive*}; B = B; std::string = std::basic_string<char>]’|
    /usr/local/include/odfaeg/Core/serialization.h|96|required from ‘void odfaeg::Serializer<B>::serialize(std::string, std::string, Archive*) [with Archive = odfaeg::ITextArchive; B = B; std::string = std::basic_string<char>]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|41|required from ‘void B::BKEY::serialize_object(std::string, std::string, Archive*) [with Archive = odfaeg::ITextArchive; std::string = std::basic_string<char>]’|
    /usr/local/include/odfaeg/Core/archive.h|539|required from ‘void odfaeg::ITextArchive::operator()(O*&, D ...) [with O = B; D = {}; <template-parameter-1-3> = void; <template-parameter-1-4> = void; <template-parameter-1-5> = void; <template-parameter-1-6> = void]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|161|required from here|
    /usr/include/c++/4.9/tuple|172|error: cannot declare field ‘std::_Head_base<1ul, odfaeg::IRefVal<odfaeg::ITextArchive*>, false>::_M_head_impl’ to be of abstract type ‘odfaeg::IRefVal<odfaeg::ITextArchive*>’|
    /usr/local/include/odfaeg/Core/fastDelegate.h|13|note:   because the following virtual functions are pure within ‘odfaeg::IRefVal<odfaeg::ITextArchive*>’:|
    /usr/local/include/odfaeg/Core/fastDelegate.h|15|note:     T& odfaeg::IRefVal<T>::get() [with T = odfaeg::ITextArchive*]|
    /usr/local/include/odfaeg/Core/fastDelegate.h|16|note:     std::unique_ptr<odfaeg::IRefVal<T> > odfaeg::IRefVal<T>::clone() const [with T = odfaeg::ITextArchive*]|
    ||=== Build failed: 8 error(s), 38 warning(s) (0 minute(s), 1 second(s)) ===|
    Voila merci d'avance pour l'aide.

  6. #26
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::tuple<O*, IRefVal<A>...> params;
    Comme tu passes l'argument IRefVal<A> par valeur et qu'il s'agit d'une classe abstraite, cela fait déjà deux erreurs relevées par le compilateur. Il faudrait le passer par référence ou pointeur. En plus, les "..." ne devraient-ils pas être placés avant le '>'? Je ne comprends pas cette syntaxe.

    Une autre erreur vient d'une invocation d'un constructeur par défaut de reference_wrapper, qui n'en a pas. Je ne suis pas sûr de ce qu'il y a derrière, puisque c'est dans le code du tuple que l'invocation a lieu.

    La dernière erreur vient de l'absence d'un opérateur d'assignement (operator=) entre IRefVal et int. Dans ton code, effectivement, il n'y a que le constructeur, donc '=' ne fonctionne que pour l'initialisation, par pour une modification de la valeur, cas dans lequel operator= est appelé.

    Ton code ne va pas être aisé à maintenir... :-)

  7. #27
    Invité
    Invité(e)
    Par défaut
    Bon, j'ai plusieurs idées, mais, en effet ça ne sera pas facile.

    La 1ère consiste à créer une structure qui va faire l'instanciation pour chaque élément du tuple.

    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
     
    template <int N, typename T, typename... V>
    struct warp_tuple {
     
    };
    template <int N, typename T, typename HV, typename...TV>
    struct warp_tuple <N, T, HV, TV...> {
        static void warp(T tuple, HV val, TV... vals) {
            std::get<N>(tuple) = RefVal<HV>(val);
            warp_tuple<N-1, T, TV...>::warp(tuple, val, vals...);
        }
    };
    template <int N, typename T, typename HV>
    struct warp_tuple <N, T, HV> {
        static void warp(T tuple, HV val) {
            std::get<0>(tuple) = RefVal<HV>(val);
        }
    };

    Et d'utiliser un pointeur sur IRefVal pour qu'il l'instancie à nullptr dans le constructeur de la classe tuple, plutôt que de rechercher le constructeur par défaut qui n'existe pas.

    Je ne sais pas si ça va marcher, mais, on verra...

  8. #28
    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
    Ca ne te parait pas "trop"?
    Une structure pour wrapper un tuple , qui wrappera un machin truc qui ...

    Utilise une fonction libre, tu n'a pas besoin d'une struct vide pour contenir une fonction static.
    Il y a les namespaces, en cas de besoin.
    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

  9. #29
    Invité
    Invité(e)
    Par défaut
    Pour itérer sur le tuple il ne faut pas une structure avec une spécialisation de template ?

  10. #30
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    template <int N, typename T, typename HV, typename...TV>
    struct warp_tuple <N, T, HV, TV...> {
        static void warp(T tuple, HV val, TV... vals) {
            std::get<N>(tuple) = RefVal<HV>(val);
            warp_tuple<N-1, T, TV...>::warp(tuple, val, vals...);
        }
    };
    template <int N, typename T, typename HV>
    struct warp_tuple <N, T, HV> {
        static void warp(T tuple, HV val) {
            std::get<0>(tuple) = RefVal<HV>(val);
        }
    };
    Ceci déclare une class (struct) template, dont chaque instance (de la template) est uniquement composé d'une méthode static.
    pourquoi ne pas passer directement par une fonction.

    telle que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <int N, typename T, typename HV, typename...TV>
    void warp_tuple(T tuple, HV val, TV... vals) {
            std::get<N>(tuple) = RefVal<HV>(val);
            warp_tuple<N-1, T, TV...>(tuple, val, vals...);
    };
     
    template <int N, typename T, typename HV>
    void warp_tuple(T tuple, HV val) {
            std::get<0>(tuple) = RefVal<HV>(val);
    };
    Et à l'usage, ce n'est pas moins template-déductible que ton code.

    Mais as-tu réellement besoin de passer par une fonction template récursive juste pour réinitialiser une tuple?
    tu ne crois pas que quelque chose comme make_tuple et forward_as_tuple ne font pas le travail?
    référence sur std::tuple (ou std::tuple&)

    J'imagine aisément l'appel auto tuple = make_tuple(12, &bidule, std::ref(refered));.

    ps: et je ne parle pas de la magie de std::tie / std::ignore
    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

  11. #31
    Invité
    Invité(e)
    Par défaut
    Ca ne fonctionne pas, il me dit que le type tuple_element machin est incomplet.

  12. #32
    Invité
    Invité(e)
    Par défaut
    Bon j'ai essayé de redéfinir l'opérateur= et ça compile :

    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
     
    template<class T>
    struct IRefVal {
    	IRefVal()=default;
    	virtual T& get() =0;
    	virtual std::unique_ptr<IRefVal> 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>(*this); }
     
    private:
    	T val;
    };
    template<class T>
    struct RefVal {
        RefVal() = default;
    	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) {
            IRefVal<T>* irv = rv.get();
            irv->set(t);
    	}
    	T& get() const
    	{ return rv->get(); }
     
    private:
    	std::unique_ptr<IRefVal<T>> rv;
    };
     
    template<class T>
    struct ToStoreImpl
    { using type = T; };
     
    template<class T>
    struct ToStore
    	: ToStoreImpl<std::remove_reference_t<T>>
    {};
     
    template<class T>
    using ToStore_t = typename
    	ToStore<T>::type;

    Cependant, j'ai un crash à l'exécution dans la classe std::tuple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #0 0x401ee4	odfaeg::RefVal<A*>::operator=(this=0x606028, t=@0x7fffffffe238: 0x7fffffffe2c0) (/usr/local/include/odfaeg/Core/fastDelegate.h:93)
    #1 0x401d7d	std::_Tuple_impl<0ul, odfaeg::RefVal<A*>, odfaeg::RefVal<int> >::operator=<A*<int> >(this=0x606018, __in=<unknown type in /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/bin/Debug/ODFAEG-DEMO, CU 0x0, DIE 0x133d4>) (/usr/include/c++/4.9/tuple:366)
    #2 0x401a10	std::tuple<odfaeg::RefVal<A*>, odfaeg::RefVal<int> >::operator=<A*, int>(std::tuple<A*, int>&&) (this=0x606018, __in=<unknown type in /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/bin/Debug/ODFAEG-DEMO, CU 0x0, DIE 0x12e61>) (/usr/include/c++/4.9/tuple:642)
    #3 0x401587	odfaeg::FastDelegate2<A<int> >::FastDelegate2<int>(void (A::*)(int) (/usr/local/include/odfaeg/Core/fastDelegate.h:271)
    #4 0x401023	odfaeg::FastDelegate<void>::FastDelegate<A<int> > (this=0x7fffffffe2d0, f=(void (A::*)(A * const, int) (/usr/local/include/odfaeg/Core/fastDelegate.h:449)
    #5 0x400df7	main() (/home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp:106)
    Qu'est ce que ça signifie ?

  13. #33
    Invité
    Invité(e)
    Par défaut
    C'est bon j'ai trouvé, en fait, il fallait simplement que je crée une instance de wrapper dans std::make_tuple, sinon, le wrapper ne contient rien :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    params = std::make_tuple(RefVal<O*>(object), RefVal<A>(args)...);

    Voila j'ai enfin un système de callback qui fonctionne pour tout les cas!

    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
     
    #include<iostream>
    #include<string>
    #include <fstream>
    #include <functional>
    #include "odfaeg/Core/fastDelegate.h"
    #include "odfaeg/Core/serialization.impl"
    using namespace std::literals;
    using namespace std::placeholders;
     
    void foo(int i, int j)
    { std::cout << i << j; }
     
    struct A {
        A() {
            var = 10;
        }
    	void foo(int i)
    	{ std::cout << i; }
    	template <typename A>
    	void serialize (A & ar) {
            ar(var);
    	}
    	int var;
    };
     
    struct B {
        B() {
            c = "serialize base";
        }
    	virtual void foo()
    	{ std::cout << 1; }
    	virtual void print() {
            std::cout<<c<<std::endl;
    	}
    	template <typename A>
    	void vtserialize (A * ar) {
            (*ar)(c);
    	}
    	virtual ~B();
    	std::string c;
    	REGISTER_BASE(BKEY, B)
    };
     
    B::~B(){}
     
    struct C : B {
        C () {
            c = "serialize derived";
        }
        void foo();
        void print () {
            B::print();
            std::cout<<c<<std::endl;
        }
        template <typename A>
    	void vtserialize (A * ar) {
            B::vtserialize(ar);
            (*ar)(c);
    	}
    	std::string c;
    };
     
    void C::foo(){ std::cout << 2; }
    REGISTER_DERIVED(C, B, C)
     
    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 foo (int *ri) {  std::cout<<*ri; }
    void foo (int& ri) {  std::cout<<ri; }
    int main(){
        EXPORT_CLASS_GUID(C, B, C)
        void(*f)(int, int) = &foo;
        odfaeg::FastDelegate<void> f1(std::bind(f,3 , _1), 3);
        f1.setParams(4);
    	f1();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate<void> f2(
    		[](int i, int j){ std::cout << i << j; },
    		7,8
    	);
    	f2();
    	f2.setParams(9,10);
    	f2();
    	std::cout << std::endl;
     
    	int i = 11;
    	odfaeg::FastDelegate<void> f3(
    		[i](int j){ std::cout << i << j; },
    		12
    	);
    	f3();
    	f3.setParams(13);
    	f3();
    	std::cout << std::endl;
     
    	A a;
    	odfaeg::FastDelegate<void> f4(&A::foo,&a,14);
    	f4();
    	f4.setParams(&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,&c);
    	f6();
    	f6.setParams(b);
    	f6();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate<void> f7(D(),16);
    	f7();
    	f7.setParams(17);
    	f7();
    	std::cout << std::endl;
     
    	odfaeg::FastDelegate<void> f8(bar,"ab"s);
    	f8();
    	f8.setParams("abc"s);
    	f8();
    	std::cout << std::endl;
    	int pi = 1;
        odfaeg::FastDelegate<void> f9(foo, &pi);
    	f9();
    	std::cout << std::endl;
    	pi=2;
    	f9();
    	std::cout << std::endl;
    	odfaeg::FastDelegate<int> f10(goo,18);
    	std::cout << f10();
    	f10.setParams(19);
    	std::cout << f10();
    	std::cout << std::endl;
    	void(*fu)(int&) = &foo;
    	int vi=1;
    	odfaeg::FastDelegate<void> f11(fu, std::ref(vi));
    	f11();
    	std::cout << std::endl;
    	vi=2;
    	f11();
    	std::cout << std::endl;
    }

    Le c++14 c'est trop bien!

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

Discussions similaires

  1. [astuce] Comment passer des résultats en sortie par référence
    Par Hibou57 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 26/08/2007, 20h12
  2. Comment passer des argument a un script php ?
    Par Florina dans le forum Linux
    Réponses: 2
    Dernier message: 11/12/2005, 14h38
  3. [script SQL]comment passer des parametres a un scrip sql?
    Par la7su dans le forum Langage SQL
    Réponses: 5
    Dernier message: 23/03/2005, 10h55
  4. Réponses: 7
    Dernier message: 30/12/2004, 12h01

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