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 :

Crash lors du passage d'un objet à un tuple que je cast par la suite.


Sujet :

Langage C++

  1. #1
    Invité
    Invité(e)
    Par défaut Crash lors du passage d'un objet à un tuple que je cast par la suite.
    Salut, je possède une classe qui me sert juste de type generique pour toutes les fonctions, bref, voici le code :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
     
    #ifndef ODFAEG_FAST_DELEGATE_HPP
    #define ODFAEG_FAST_DELEGATE_HPP
    #include <functional>
    #include <iostream>
    #include "export.hpp"
    #include "erreur.h"
    #include <tuple>
    #include <utility>
    #include <memory>
    /**
      *\namespace odfaeg
      * the namespace of the Opensource Development Framework Adapted for Every Games.
      */
    namespace odfaeg {
    /**
    *  \file  fastDelegate.h
    *  \class IRefVal
    *  \brief Interface for the warppers to references, values and pointers.
    *  This class is used store references, pointers and values to pass to the callack's functions.
    *  \param T : the type of the value to wrap.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct IRefVal {
        /**\fn
        *  \brief default constructor
        */
    	IRefVal()=default;
    	/**\fn T& get()
            *  \brief get the reference of the wrapped type.
            *  \return the reference of the wrapped type.
            */
    	virtual T& get() =0;
    	/**\fn std::unique_ptr<IRefVal<T>> clone() const = 0;
            *  \brief copy the wrapper.
            *  \return the copied wrapper.*/
    	virtual std::unique_ptr<IRefVal<T>> clone() const = 0;
    	/**\fn destructor*/
    	virtual ~IRefVal(){}
     
    protected:
        /**\fn IRefVal(const IRefVal&)
        *  \brief constructor, pass the reference to wrap.
        *  \param const IRefVal& : the reference to wrap.
        */
    	IRefVal(const IRefVal&){}
    	/** \fn IRefVal& operator=(const IRefVal&)
            *   \brief affector.
            *   \param const IRefVal& : the wrapper to affect.
            *   \return the affected wrapper.*/
    	IRefVal& operator=(const IRefVal&)
    	{ return *this; }
    };
    /**
    *  \file  fastDelegate.h
    *  \class Ref
    *  \brief Warp a reference. (Use std::reference_wrapper so we can pass a reference with std::ref)
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct Ref : IRefVal<T> {
        /**
        *\fn Ref(const std::reference_wrapper<T>& r)
        *\brief Constructor : pass an std::reference_wrapper to the wrapper.
        *\param std::reference_wrapper<T>& r : the reference_wrapper.
        */
    	Ref(const std::reference_wrapper<T>& r)
    		: ref(r)
    	{}
    	/**
            * \fn T& get()
            * \brief return a reference to an object.
            * \return T& the reference to the object.
            */
    	T& get()
    	{ return ref.get(); }
    	/**
            * \fn std::unique_ptr<IRefVal<T>> clone() const
            * \brief copy the reference wrapper.
            * \return std::unique_ptr<IRefVal<T>> : the cloned wrapper.
            */
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<Ref>(*this); }
    private:
    	std::reference_wrapper<T> ref; /**> the std::reference_wrapper which warp the reference.*/
    };
    /**
    *  \file  fastDelegate.h
    *  \class Val
    *  \brief Warp a value.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct Val : IRefVal<T> {
        /**\fn Val(const T& t)
        *  \brief pass a value to the wrapper.
        *  \param const T& t : the value to pass.
        */
    	Val(const T& t)
    		: val(t)
    	{}
    	/** \fn
            *   \brief return the value
            *   \return T& : return the value.
            */
    	T& get()
    	{ return val; }
    	/**
            * \fn std::unique_ptr<IRefVal<T>> clone() const
            * \brief copy the value wrapper.
            * \return std::unique_ptr<IRefVal<T>> : the cloned wrapper.
            */
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<Val>(*this); }
    private:
    	T val; /**> T val : keep the value of the wrapper.*/
    };
    /**
    *  \file  fastDelegate.h
    *  \class Ref
    *  \brief Warp a pointer.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct Pointer : IRefVal<T> {
        /**\fn Pointer(const T* t)
        *  \brief pass a pointer to the wrapper.
        *  \param const T* t : the pointer to pass.
        */
    	Pointer(const T* t)
    		: pointer(t)
    	{}
    	/** \fn
            *   \brief return the pointer of the wrapper.
            *   \return T& : return the pointer.
            */
    	T& get()
    	{ return pointer; }
    	/**
            * \fn std::unique_ptr<IRefVal<T>> clone() const
            * \brief copy the pointer wrapper.
            * \return std::unique_ptr<IRefVal<T>> : the cloned wrapper.
            */
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<Pointer<T>>(*this); }
     
    private:
    	T pointer; /**> T pointer : keep the pointer of the wrapper.*/
    };
    /**
    *  \file  fastDelegate.h
    *  \class RefVal
    *  \brief Wrap a pointer, a value or a reference and keep a pointer to the generic wrapper.
    *  Call the right constructor depending on the wrapper's or value's type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct RefVal {
        /**
        * \fn RefVal (const T& t)
        * \brief constructor : construct a wrapper to a value
        * \param const T& t : the value to
        */
    	RefVal(const T& t)
    	: rv(std::make_unique<Val<T>>(t))
    	{}
    	/**
        * \fn RefVal (const std::reference_wrapper<T>& r)
        * \brief constructor : construct a wrapper to an std::reference_wrapper.
        * \param const std::reference_wrapper<T>& : the std::reference_wrapper to pass.
        */
    	RefVal(const std::reference_wrapper<T>& r)
    	: rv(std::make_unique<Ref<T>>(r))
    	{}
    	/**
        * \fn RefVal (const std::reference_wrapper<T>& r)
        * \brief constructor : construct a wrapper to a pointer.
        * \param const T*& p : the pointer to pass.
        */
    	RefVal(const T*& p)
    	: rv(std::make_unique<Pointer<T>>(p))
    	{}
    	/** \fn RefVal (const RefVal& rhs)
            *   \brief copy constructor, copy the wrapper with the right wrapper type.
            *   \param const RefVal& rhs : the wrapper to copy.
            */
    	RefVal(const RefVal& rhs)
        {
            rv = rhs.rv->clone();
        }
        /** \fn RefVal& operator= (const RefVal& rhs)
            *   \brief affector.
            *   \param const RefVal& rhs : the wrapper to affect.
            */
    	RefVal& operator=(const RefVal& rhs)
    	{ rv=rhs.rv->clone(); return *this; }
    	/** \fn T& get() const
            *   \brief get the wrapper.
            *   \return a unique pointer to the generic wrapper interface.
            */
    	T& get() const
    	{ return rv->get(); }
     
    private:
    	std::unique_ptr<IRefVal<T>> rv; /**> a pointer to the generic wrapper interface.*/
    };
    //Classe de trait pour déterminer le type à stocker
     
    //(Interne) Cas général
    /**
    *  \file  fastDelegate.h
    *  \class ToStoreImpl
    *  \param T the type of the wrapper.
    *  \brief Trait class which use an alias on a wrapped type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct ToStoreImpl
    { using type = T; };
    /**
    *  \file  fastDelegate.h
    *  \class ToStoreImpl
    *  \param T the type warpped in the warpper.
    *  \brief Trait class with keep an alias on the wrapped type.
    *  This class is specialized for std::_reference_wrapper type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct ToStoreImpl<std::reference_wrapper<T>>
    { using type = T; };
    /**
    *  \file  fastDelegate.h
    *  \class ToStore
    *  \param T the type of the wrapper.
    *  \brief Trait class with keep an alias of the wrapper type. (without the reference)
    *  the inheritance use the right specialized templated class to hold the type of the wrapped object
    *  depending on the wrapper type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct ToStore
    	: ToStoreImpl<std::remove_reference_t<T>>
    {};
    /**
    *  \file  fastDelegate.h
    *  \class ToStore_t
    *  \param T the type of the wrapped object.
    *  \brief Trait class which hold an alias to the real type of the wrapped type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    using ToStore_t = typename
    	ToStore<T>::type;
    /**
    *  \file  fastDelegate.h
    *  \class DynamicWrapper
    *  \param R the return type of the wrapped functor.
    *  \param C the class type of the wrapped functor.
    *  \param ArgT the arguments types of the wrapped functor.
    *  \brief This class warp a function pointer to a member function.
    *  I don't use an std::function directly here to keep the class type of the member function pointer
    *  because if the passed object is polymorphic, I need to apply a dynamic cast
    *  before calling the member function pointer on the object.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class R, class C, class... ArgT>
    struct DynamicWrapper {
        /**\fn DynamicWrapper(R(C::*pf)(ArgT...)) : pfunc(pf)
        *  \brief warp a pointer to a member function.
        *  \param R(C::*pf)(ArgT...) : the pointer to the member function.
        */
    	DynamicWrapper(R(C::*pf)(ArgT...)) : pfunc(pf){}
    	/**\fn R operator()(O* o, ArgU&&... arg) const
            *  \brief call the member function's pointer witht he given object and the given argument
            *  apply a dynamic_cast in case of the type of the object and the type of the classe containing the member function
            *  are not the same. (If the object is polymoprhic)
            *  If the cast fails it means that the object is not polymorphic so it throws an error.
            *  \param O* o : the object onwich to call the member function's pointer.
            *  \param ArgU&& arg : the arguments of the member function's pointer to call.
            */
    	template<class O, class... ArgU>
    	R operator()(O* o, ArgU&&... arg) const
    	{
    		if(dynamic_cast<C*>(o))
    			return (dynamic_cast<C*>(o)->*pfunc)(std::forward<ArgU>(arg)...);
            throw Erreur(0, "Invalid cast : types are nor polymorphic!", 1);
    	}
    	template<class O, class... ArgU>
    	R operator()(O& o, ArgU&&... arg) const
    	{
    		if(dynamic_cast<C&>(o))
    			return (dynamic_cast<C&>(o)->*pfunc)(std::forward<ArgU>(arg)...);
            throw Erreur(0, "Invalid cast : types are nor polymorphic!", 1);
    	}
    private:
    	R (C::*pfunc)(ArgT...); /**> a pointer to a member's function.*/
    };
    /**
    *  \file  fastDelegate.h
    *  \class DynamicFunction
    *  \param F the type of the function.
    *  \brief Generic class for every functors type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class F>
    class DynamicFunction;
    /**
    *  \file  fastDelegate.h
    *  \class DynamicFunction
    *  \param R the return type of the function.
    *  \param ArgT... the type of the arguments of the function.
    *  \brief Specialized template class for functors. (inherit from std::function)
    *  build a functor with the right constructor depending a the pointer's function type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class R, class... ArgT>
    class DynamicFunction<R(ArgT...)>
    	: std::function<R(ArgT...)>
    {
        /**> just an alias to the type of the base class.*/
    	using Base = std::function<R(ArgT...)>;
     
    public:
        /**
        * \fn DynamicFunction(F&& f)
        * \brief pass a functor to the std::function.
        * \param F&& f : the functor to pass to the std::function.
        */
    	template<class F>
    	DynamicFunction(F&& f) : Base(std::forward<F>(f))
    	{}
    	/** \fn DynamicFunction (R (C::*pf)(ArgU...))
            *   \brief pass a pointer to a member's function to the DynamicWrapper, and then
            *   pass this wrapper to the std::function, so, the std::function call the operator() of the DynamicWrapper class
            *   and not the operator() of the std::function class so we can perform the dynamic_cast if necessary.
            *   \param R(C::*pf)(ArgU...) : the pointer to the member's function.
            *   \
            */
    	template<class C, class... ArgU>
    	DynamicFunction(R(C::*pf)(ArgU...))
    		: Base(DynamicWrapper<R,C,ArgU...>(pf))
    	{}
    	/**> just an allias to the operator() of the base class.*/
        using Base::operator();
    };
    /**
    *  \file  fastDelegate.h
    *  \class Delegate
    *  \param R the return type of the function.
    *  \brief Interface with can hold a delegate to every delegates types.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class R>
    struct Delegate {
        /**\fn Delegate()
        *  \brief default constructor.
        */
    	Delegate() =default;
    	/**\fn virtual std::unique_ptr<Delegate> clone() const = 0;
        *  \brief pure virtual function to redefine in the subclass to copy the delegate.
        *  \return std::unique_ptr<Delegate> a pointer to the copied delegate.
        */
    	virtual std::unique_ptr<Delegate> clone() const = 0;
    	/**\fn R operator()() = 0;
        *  \brief pure virtual function to redefines to call the std::function of the delegate.
        *  \return R : return the value returned by the std::function.
        */
    	virtual R operator()() = 0;
    	/** /fn virtual Delegate()
            * \brief destructor
            */
    	virtual ~Delegate(){}
     
    protected:
        /**
        * \fn Delegate (const Delegate&) {}
        * \brief copy constructor.
        * \param const Delegate& : the delegate to copy.
        */
    	Delegate(const Delegate&){}
    	/**
        * \fn Delegate& operator= (const Delegate&) {}
        * \brief affector.
        * \return Delegate& : return a reference to the current delegate.
        */
    	Delegate& operator=(const Delegate&)
    	{
            return *this;
    	}
    };
    /**
    *  \file  fastDelegate.h
    *  \class FastDelegateImpl
    *  \brief Implementation of the delegate's interfaces.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class R, class... ArgT>
    struct FastDelegateImpl : Delegate<R> {
        /** \fn FastDelegateImpl(F&& f, ArgU&&... arg)
        *   \brief constructor : create the delegate with the functor and the arguments value passed.
        */
    	template<class F, class... ArgU>
    	FastDelegateImpl(F&& f, ArgU&&... arg)
    		: func(std::forward<F>(f))
    		, param(std::forward<ArgU>(arg)...)
    	{}
    	/** \fn std::unique_ptr<Delegate<R>> clone() const
        *   \brief make a copy of the delegate.
        *   \return the copied delegate.
        */
    	std::unique_ptr<Delegate<R>> clone() const
    	{ return std::make_unique<FastDelegateImpl>(*this); }
    	/** \fn R operator()()
            *   \brief call the std::function of the delegate.
        *   \return the value returned by the std::function.
        */
    	R operator()()
    	{ return call(std::make_index_sequence<sizeof...(ArgT)>()); }
    	/** \fn R operator()()
            *   \brief changed the parameter's values of the std::function.
        *   \param ArgU&&... args : the values for the parameters to the delegate's function.
        */
    	template<class... ArgU>
    	void setParams(ArgU&&... arg)
    	{ param=std::make_tuple(std::forward<ArgU>(arg)...); }
     
    private:
        /** \fn R call(std::index_sequence<I...>)
            *   \brief pass each elements of the tuple to the std::function and unwarp them.
        *   \param std::index_sequence<I...> : a sequence of indexes to get every elements of the tuple.
        *   \return the value returned by the std::function.
        */
    	template<std::size_t... I>
    	R call(std::index_sequence<I...>)
    	{ return func(std::get<I>(param).get()...); }
    	std::function<R(ArgT&...)> func; /**> a functor whith hold the pointer to a callback function.*/
    	std::tuple<RefVal<ArgT>...> param; /**> the wrapped values of the parameters to pass to the callback's function.*/
    };
    /**
    *  \file  fastDelegate.h
    *  \class FastDelegate
    *  \brief Class used for the type erasure,
    *  which allow the user be able to store a set of different callback's functions types with the same return type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class R>
    struct FastDelegate {
        /**\fn default constructor
        */
        FastDelegate() = default;
        /**\fn FastDelegate (F&& f, Arg&& arf)
        *  \param F&& f : the functor to pass.
        *  \param Arg&&... arg : arguments to pass to the functor.
        */
        template<class F, class... Arg>
    	FastDelegate(F&& f, Arg&&... arg) :
    		delegate(std::make_unique
    			<FastDelegateImpl<R,ToStore_t<Arg>...>>
    			(std::forward<F>(f),std::forward<Arg>(arg)...)
    		)
    	{}
     
    	/**\fn FastDelegate (FastDelegate& rhs)
            *  \brief copy constructor.
            *  \param FastDelegate& rhs : the delegate to copy.
            */
    	FastDelegate(FastDelegate& rhs)
    		: delegate(rhs.delegate->clone())
    	{}
    	/**\fn FastDelegate (const FastDelegate& rhs)
            *  \brief copy constructor.
            *  \param const FastDelegate& rhs : the delegate to copy.
            */
    	FastDelegate(const FastDelegate& rhs)
    		: delegate(rhs.delegate->clone())
    	{}
    	/**\fn FastDelegate (FastDelegate& rhs)
            *  \brief move constructor.
            *  \param FastDelegate&& rhs : the delegate to move.
            */
    	FastDelegate(FastDelegate&& rhs) =default;
    	/**\fn FastDelegate& operator= (FastDelegate& rhs)
            *  \brief affect the content of the delegate to the delegate.
            *  \param const FastDelegate& rhs : the delegate affect.
            *  \return FastDelegate& : the affected delegate.
            */
    	FastDelegate& operator=(const FastDelegate& rhs)
    	{ return operator=(FastDelegate(rhs)); }
    	/**\fn FastDelegate& operator= (FastDelegate& rhs)
            *  \brief affect and move the content of the delegate to the delegate.
            *  \param const FastDelegate& rhs : the delegate to move and to affect.
            *  \return FastDelegate& : the moved and affected delegate.
            */
    	FastDelegate& operator=(FastDelegate&&) =default;
    	/**\fn R operator()() const;
            *  \brief call the std::function of the delegate.
            *  \return the value returned by the std::function.
            */
    	R operator()() const
    	{ return (*delegate)(); }
    	/**\fn setParams(Arg&&... arg)
            *  \brief change the parameter's values of the delegate.
            *  \return Arg&&... arg : the values of the parameters of the delegate.
            */
    	template<class... Arg>
    	void setParams(Arg&&... arg)
    	{
    		using StaticType =
    			FastDelegateImpl<R,ToStore_t<Arg>...>*;
    		static_cast<StaticType>(delegate.get())->setParams(std::forward<Arg>(arg)...);
    	}
    private:
    	std::unique_ptr<Delegate<R>> delegate; /**> holds the pointer to the generic delegate.*/
    };
    }
    #endif

    Le problème vient de la fonction setParams qui ne passe pas bien un pointeur sur un objet polymorphique, je m'explique ;

    J'ai un classe abstraite de base (Entity), une classe abstraite dérivée (Model) qui hérite de Entity, et une troisième classe (Wall) qui hérite de Model. (Le crash ne survient que dans ce cas là)

    Donc pour une classe B qui hérite directement de Entity, pas de problème, par contre pour les classes qui n'héritent pas directement de Entity, j'ai ce crash.

    Le crash survient lorsque je fait appel à setParams, on dirait que les valeurs de mes variables de ma sous classe son modifiée lors du dynamic_cast (dans le dynamic wrapper) et je ne comprend pas pourquoi, bref voici un code :

    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
     
    int main (int argv, char* argc[]) {
        EXPORT_CLASS_GUID(BoundingVolumeBoundingBox, odfaeg::BoundingVolume, odfaeg::BoundingBox)
        EXPORT_CLASS_GUID(EntityTile, odfaeg::g2d::Entity, odfaeg::g2d::Tile)
        EXPORT_CLASS_GUID(EntityWall, odfaeg::g2d::Entity, odfaeg::g2d::Wall)
        EXPORT_CLASS_GUID(EntityShadowTile, odfaeg::g2d::Entity, odfaeg::g2d::ShadowTile)
        EXPORT_CLASS_GUID(EntityShadowWall, odfaeg::g2d::Entity, odfaeg::g2d::ShadowWall)
        odfaeg::Texture tex;
        tex.loadFromFile("tilesets/murs.png");
        odfaeg::g2d::Tile* tWall = new odfaeg::g2d::Tile(&tex, odfaeg::Vec3f(0, 0, 0), odfaeg::Vec3f(100, 100, 0), sf::IntRect(100, 0, 100, 100));
        odfaeg::g2d::Entity* w = new odfaeg::g2d::Wall(3, 80, tWall,odfaeg::g2d::AmbientLight::getAmbientLight(), odfaeg::g2d::Shadow::SHADOW_TYPE::SHADOW_TILE);
        std::ofstream ofs("fichierDeSerialisation");
        odfaeg::OTextArchive oa(ofs);
        void(odfaeg::g2d::Wall::*f)(odfaeg::OTextArchive&) = &odfaeg::g2d::Wall::vtserialize;
     
        odfaeg::FastDelegate<void> fd(f, new odfaeg::g2d::Wall(), std::ref(oa));
        fd.setParams(w, std::ref(oa));
        fd();
        ofs.close();
        std::ifstream ifs("fichierDeSerialisation");
        odfaeg::ITextArchive ia(ifs);
        ia(w2);
        ifs.close();   
        return 0;
        MyAppli app(sf::VideoMode(800, 600, 32), "Test odfaeg");
        return app.exec();
    }

    Les valeurs des variables de ma classe Wall changent tout seules. :o

    Et donc lors de l'appel sur mon delegate fd, ça crash.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bon, après avoir fait quelque std::cout par ci par là, je me rend compte en fait qu'il ne va jamais dans le constructeur de DynamicFunction (dans aucun des 2), du coup il ne fait, aucun cast, pour cela que ça crash.

    Arf, pourquoi j'ai choisi d'utiliser std::function, mon côté pervers de réinventer la roue me permet souvent de me déjouer de beaucoup de problèmes. :/

  3. #3
    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
    Ligne 465 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DynamicFunction<R(ArgT&...)> func;

  4. #4
    Invité
    Invité(e)
    Par défaut
    Ha oui je viens de le voir juste avant que tu poste ton message et j'ai changé le code mais apparemment ça à l'air de faire la même chose que la version sans le DynamicWrapper!

    Par contre, après le cast ici (cette fois ça rentre bien dedans)

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template<class O, class... ArgU>
    	R operator()(O* o, ArgU&&... arg) const
    	{
    	    std::cout<<"cast! "<<std::endl;
    		if(dynamic_cast<C*>(o))
    			return (dynamic_cast<C*>(o)->*pfunc)(std::forward<ArgU>(arg)...);
            throw Erreur(0, "Invalid cast : types are nor polymorphic!", 1);
    	}

    J'ai toujours le même problème, je sais pas, il ne cast pas bien...

  5. #5
    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
    Je sais pas d'où vient ton problème, mais c'est pas ton histoire de hiérarchie. J'ai testé avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    struct Entity
    {
    	virtual void foo()
    	{ std::cout << 1; }
     
    	virtual ~Entity(){}
    };
     
    struct Model : Entity
    {
    	 void foo()
    	{ std::cout << 2; }
    };
     
    struct Wall : Model
    {
    	void foo()
       { std::cout << 3; }
    };
    Et ton/mon code appel bien le bon. Tu peux faire voir Entity/Model/Wall ?

  6. #6
    Invité
    Invité(e)
    Par défaut
    Le plus bizarre c'est que :

    -En compilation ça passe.
    -Je n'ai aucune exception lancée, donc, il me cast bien le type de base (Entity), en type dérivé (Wall).

    Par contre, je ne retrouve plus les même valeurs pour les variables de la class wall, aussi bien celle des classes de bases que celle des classes dérivée, du coup il essaye de lire à des endroits invalide en mémoire.

    Si tu veux le code des classes Entity, Model et Wall, voici le lien de mon répertoire git-hub : https://github.com/Lolilolight/ODFAEG(Elles sont dans le dossier /include/odfaeg/Graphics/2D pour les fichiers d'en tête et /src/odfaeg/Graphics/2D pour les fichiers sources)

    Ce que je ne comprends pas c'est que avec un code tout simple je n'ai aucun problème :

    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
     
    struct Entity
    {
    	virtual void foo()= 0;
    	virtual ~Entity(){}
    };
     
    struct Model : Entity
    {
    public :
        Model() {
            i = 0;
        }
        Model(int i) : i(i) {
        }
        template <typename Archive>
        void serialize(Archive & a) {
            std::cout<<i<<std::endl;
        }
        virtual void foo() = 0;
    private :
        int i;
    };
     
    struct Wall : Model
    {
    public :
       Wall() {
           i = 0;
       }
       Wall (int i) : Model(i), i(i) {}
       template <typename Archive>
       void serialize(Archive & a) {
           Model::serialize(a);
           std::cout<<"i : "<<i<<std::endl;
       }
       void foo()
       { std::cout << i; }
    private :
        int i;
    };

    La valeur de i ne change pas et j'ai bien 3.

    Tandis que lorsque j'essaye avec ma classe plus complexe (qui possède des attributs vers d'autres classes (aussi bien des attributs polymorphique que des autres) cela ne fonctionne pas, mon objet n'est pas bien passé à mon tuple en tout cas :

    Pourtant, cela fonctionne bien lorsque je fais un dynamic_cast sans passer par le tuple et je n'ai jamais eu aucun problème avec toutes ces classes, mais dès que je veux forwarder les éléments dans le tuple avant de les passer à mon foncteur, mon objet n'est pas bien "forwardé.".

    Alors, après le cast je me retrouve avec ceci comme valeur :

    0 pour le type du mur, 0 pour la hauteur du mure, 49 pour la valeur de l'enum, hors que je l'ai créer avec 3, 80 et 1 comme valeur.

    Pareil pour la super classe Model, la tailles de mon vecteur segments, est un nombre trop grand du style 18446744073709551574. (Hors que elle ne devrait valoir que 2 je pense)

    Bref, je n'ai plus du tout les même valeurs que celle que j'avais en initialisant mon mur avec le constructeur.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Bon en ayant fait quelque tests le problème semble venir..., de la classe de trait, car, j'ai essayé de faire sans passer par la classe de trait (ToStore_t et sans passer par la classe delegate) et cela fonctionne.

    Mais j'ai quelque questions :

    Je ne comprend pas très bien ce que fait A&&, surtout dans le cas ou le type de A est un pointeur, crée t'il rvalue sur une référence référençant le pointeur ?

    J'ai essayé de rajouté une classe de trait mais cela ne change rien :
    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
     
    //Classe de trait pour déterminer le type à stocker
     
    //(Interne) Cas général
    /**
    *  \file  fastDelegate.h
    *  \class ToStoreImpl
    *  \param T the type of the wrapper.
    *  \brief Trait class which use an alias on a wrapped type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct ToStoreImpl
    { using type = T; };
    /**
    *  \file  fastDelegate.h
    *  \class ToStoreImpl
    *  \param T the type warpped in the warpper.
    *  \brief Trait class with keep an alias on the wrapped type.
    *  This class is specialized for std::_reference_wrapper type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct ToStoreImpl<std::reference_wrapper<T>>
    { using type = T; };
    template<class T>
    struct ToStoreImpl<T*&>
    { using type = T*; };
     
    /**
    *  \file  fastDelegate.h
    *  \class ToStore
    *  \param T the type of the wrapper.
    *  \brief Trait class with keep an alias of the wrapper type. (without the reference)
    *  the inheritance use the right specialized templated class to hold the type of the wrapped object
    *  depending on the wrapper type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    struct ToStore
    	: ToStoreImpl<std::remove_reference_t<T>>
    {};
    /**
    *  \file  fastDelegate.h
    *  \class ToStore_t
    *  \param T the type of the wrapped object.
    *  \brief Trait class which hold an alias to the real type of the wrapped type.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T>
    using ToStore_t = typename
    	ToStore<T>::type;

  8. #8
    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
    Comment ça sans Delegate ? C'est ta classe de base, tu es bien obligé d'y passer ?

    La classe de trait sert à déterminer le type à stocker, qui est différent du type passé en paramètre. En effet si un des paramètres template est déduit à un type référence, sans rien faire tu te retrouves avec une référence dans ton tuple, ce qui va être gênant quand tu vas vouloir changer le paramètre avec setParam. D'où le passage par une classe de trait qui enlève les références et qui retourne un type-erasure pour stocker valeur ou référence (et ta classe Pointer sert à rien et est fausse, mais je crois pas que ce soit le problème ici).

    Je regarde les classes sur le dépôt avant de compléter ma réponse.

    Test en virant Pointer on sait jamais.

    Bloque explicitement constructeur de copie et opérateur d'affectation dans Entity pour prévenir de tout slicing et test pour voir.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Comment ça sans Delegate ? C'est ta classe de base, tu es bien obligé d'y passer ?
    Oui, je suis obligé d'y passer mais j'ai essayé avec le code généré par le delegate :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     std::tuple<odfaeg::RefVal<odfaeg::g2d::Entity*>, odfaeg::RefVal<std::reference_wrapper<odfaeg::OTextArchive>>> t
        = std::make_tuple(std::forward<odfaeg::RefVal<odfaeg::g2d::Entity*>>(odfaeg::RefVal<odfaeg::g2d::Entity*>(w)),
                          std::forward<odfaeg::RefVal<std::reference_wrapper<odfaeg::OTextArchive>>>(odfaeg::RefVal<std::reference_wrapper<odfaeg::OTextArchive>>(std::ref(oa))));
     
        void(odfaeg::g2d::Wall::*f)(odfaeg::OTextArchive&) = &odfaeg::g2d::Wall::vtserialize;
        std::function<void(odfaeg::g2d::Wall*, odfaeg::OTextArchive&)> fct = f;
        fct(dynamic_cast<odfaeg::g2d::Wall*>(std::get<0>(t).get()), std::get<1>(t).get());

    Qui normalement devrait, me générer un code du genre (ce code-ci fonctionne), on dirait que le problème vient ici, avec le passage au foncteur par référence :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DynamicFunction<R(ArgT&...)> func;

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Pointer sert à rien et est fausse, mais je crois pas que ce soit le problème ici).

    J'en ai besoin pour passer des arguments par pointeurs sinon j'ai une erreur en compilation (pas pour le passage de l'objet sur lequel appeler le foncteur mais pour les autres arguments)

    En effet si un des paramètres template est déduit à un type référence, sans rien faire tu te retrouves avec une référence dans ton tuple
    Je pense que le problème est quelque part par là, à part que ici je me retrouve avec une référence lors du passage des éléments de mon tuple au foncteur vu la déclaration de la référence ici :
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DynamicFunction<R(ArgT&...)> func;

    Je pense que c'est ça qui le gêne mais je vois pas comment faire sans.

  10. #10
    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 essayer de changer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    odfaeg::FastDelegate<void> fd(f, new odfaeg::g2d::Wall(), std::ref(oa));
    Par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    odfaeg::FastDelegate<void> fd(f, static_cast<Entity*>(new odfaeg::g2d::Wall()), std::ref(oa));
    ?

    Je sais que ce n'est pas ce que tu veux exactement, mais c'est pour vérifier une théorie ? Je pense avoir trouvé le problème.

    PS: Non, Pointer ne devrait pas exister, la logique du code vient de moi, je sais encore ce qui devrait ou pas exister (que tu ais eu des erreurs de compilation je le conçois, mais la solution n était pas de créer cette classe, un pointeur c'est une valeur, ça doit aller dans Val).

  11. #11
    Invité
    Invité(e)
    Par défaut
    Ok j'ai fais ce que tu m'as dis, j'ai enlevé la classe Pointer, pour que ça passe par val.

    J'ai bloqué le constructeur de copie et l'opérateur d'affectation de la classe Entity,il n'y a pas de problème de slicing.

    Et j'ai testé ça et ça ne crash plus.

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void(odfaeg::g2d::Wall::*f)(odfaeg::OTextArchive&) = &odfaeg::g2d::Wall::vtserialize;
    odfaeg::FastDelegate<void> fd(f, static_cast<odfaeg::g2d::Entity*>(new odfaeg::g2d::Wall()), std::ref(oa));
    fd.setParams(w, std::ref(oa));
    fd();

    Donc le problème viens bien de là.

  12. #12
    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
    Le problème vient très exactement d'ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    		static_cast<StaticType>(delegate.get())->setParams(std::forward<Arg>(arg)...);
    Il faut mettre un dynamic_cast et tester le retour (puis lancer ou assert en cas de retour nul).

    Le problème n'est pas réellement soluble. En faite coimme tu fais du type-erasure sur les paramètres, le type FastDelegate n'a aucune information sur ceux-ci et se base donc sur ce que tu lui passes pour déterminer l'implémentation FastDelegate a utiliser.

    Le problème c'est que la première fois tu lui passe un Wall* donc lui il utilise ca pour son implémentation, et la fois d'après un Entity* ce qui ne correspond pas.

    Je te rassure, tu avais le même problème avec ton code sans std::function donc ce n'est pas lui le problème.

    J'ai deux pistes de solution mais rien de testé :
    • Le plus simple, forcer l’utilisateur à devoir faire le cast comme je t'ai demandé de le faire pour vérifier le problème (à écrire dans la doc et dans l'assert/execption en cas d'impossibilité de dynamic_cast).
    • Ajouter un typedef/using dans les type d'une hiérarchie qui indique le type mère de manière à pouvoir le récupérer avec un trait (peut aussi être non intrusif en surchargeant directement le trait), on doit pouvoir automatiser un peu le truc avec macro/crtp.

  13. #13
    Invité
    Invité(e)
    Par défaut
    Ok oui en effet c'est assez gênant comme erreur, j'ai corriger le problème ici dans la macro et ça ne crash plus :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #define EXPORT_CLASS_GUID(ID, BASE, DERIVED) \
    { \
    REGISTER_TYPE(ID, BASE, DERIVED) \
    std::ostringstream oss##ID; \
    std::istringstream iss##ID; \
    odfaeg::OTextArchive outa##ID(oss##ID); \
    odfaeg::ITextArchive ina##ID(iss##ID); \
    DERIVED* derived##ID = new DERIVED(); \
    REGISTER_FUNC(ID, serialize, OTextArchive, BASE, DERIVED, (odfaeg::OTextArchive&), static_cast<BASE*>(derived##ID), std::ref(outa##ID)) \
    REGISTER_FUNC(ID, serialize, ITextArchive, BASE, DERIVED, (odfaeg::ITextArchive&), static_cast<BASE*>(derived##ID), std::ref(ina##ID)) \
    }

    Mais je pense que je vais essayer de faire un static_assert, ainsi, si le type ne correspond pas, ça renverra une erreur.

    Le dynamic cast j'avais déjà essaye de le faire ici :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template<class... Arg>
    	void setParams(Arg&&... arg)
    	{
    		using StaticType =
    			FastDelegateImpl<R,ToStore_t<Arg>...>*;
    		static_cast<StaticType>(delegate.get())->setParams(std::forward<Arg>(arg)...);
    	}

    Mais j'ai du le remplacer par un static_cast car je veux que le cast soit fait en fonction du type des paramètres de la fonction en compilation, et non pas à l'exécution. (Sinon ça crash car FastDelegateImpl<R,ToStore_t<odfaeg::Wall>...>* qui est sont type à l'exécution est différent de FastDelegateImpl<R,ToStore_t<odfaeg::Entity>...>* qui est son type en compilation.

  14. #14
    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
    Bha justement, c'est bien que ça crash (enfin que le dynamic_cast échoue) ça te donne le fait qu'il y ai une erreur.

    Tu ne peux pas faire un static_assert, le problème est à l’exécution, à la compilation il n'y a pas de problème. Donc exception ou assert sur le retour du dynamic_cast mais en aucun cas [/CODEINLINE]static_assert[/CODEINLINE].

  15. #15
    Invité
    Invité(e)
    Par défaut
    Ok j'ai fais ceci : (je vais essayer de rendre le message d'erreur le plus explicite possible en disant qu'il a passé à pointeur sur le type dérivé à la construction, mais qu'il utilise un pointeur sur le type de base lors de l'appel à setParam)

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    using DynamicType =
    			FastDelegateImpl<R,ToStore_t<Arg>...>*;
    		if (dynamic_cast<DynamicType>(delegate.get()))
               dynamic_cast<DynamicType>(delegate.get())->setParams(std::forward<Arg>(arg)...);
            else
                throw Erreur(0, "Bad cast!", 1);

    Ma classe de départ c'est à dire celle avec laquelle j'ai réinventer la roue faisait le static_cast automatiquement sur les pointeurs lors de l'appel à setParam si les types des pointeurs étaient différents, ce que ne fais pas std::function. :/

  16. #16
    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
    Non ton code de départ a le même problème :
    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
    namespace odfaeg {
     
    struct Delegate
    { virtual void operator()() = 0; };
     
    template<class F, class... A>
    struct FastDelegate6 : Delegate {
    	FastDelegate6(F func, A... args) {
                typedef void(*CB)(F,A...);
                CB cb = &callback;
                funct = new Functor<void(F,A...)>(cb, func);
                params = std::make_tuple(args...);
            }
    	void setParams (A... args)
    	{ params = std::make_tuple(args...); }
    	void operator()()
    	{ (*funct)(params); }
     
    private :
    	std::tuple<A...> params;
    	Functor<void(F, A...)> *funct;
    };
     
    template<class... A> 
    struct FastDelegate0 : Delegate {
    	FastDelegate0 (void(*f)(A...), A... args) {
                typedef void(*CB)(Function<void(A...)>,A... args);
                CB cb = &callback;
                funct = new Functor<void(Function<void(A...)>,A...)>(cb,Function<void(A...)>(f));
                params = std::make_tuple(args...);
            }
    	void setParams (A... args)
    		{ params = std::make_tuple(args...); }
    	void operator()()
    		{ (*funct)(params); }
     
    private :
    	std::tuple<A...> params;
    	Functor<void(Function<void(A...)>,A...)> *funct;
    };
     
    struct FastDelegate {
        template<class F, class... A>
    	FastDelegate(F f, A... args)
    	{ delegate = new FastDelegate6<F,A...>(f,args...); }
        template <class... A>
    	FastDelegate(void(*f)(A...), A... args)
    	{ delegate = new FastDelegate0<A...>(f,args...); }
        void operator()()
    	{ (*delegate)(); }
        template<class F, class... A>
    	void setFuncParams(A... args) {
            if (static_cast<FastDelegate6<F,A...>*>(delegate))
                static_cast<FastDelegate6<F,A...>*>(delegate)->setParams(args...);
        }
        template<class... A>
    	void setParams(A... args) {
            if (static_cast<FastDelegate0<A...>*>(delegate))
                static_cast<FastDelegate0<A...>*>(delegate)->setParams(args...);
        }
     
    private :
        Delegate* delegate;
    };
     
    }
    Tu fais exactement le même cast donc tu as exactement le même problème.

    On doit pouvoir arriver à quelques chose d'automatique qui implique seulement d'indiquer le type de base à une macro je pense.

  17. #17
    Invité
    Invité(e)
    Par défaut
    Bizarre, je ne me rappelle pas avoir eu de tels crash avec mon code de base. (Je voulais parlé des classes FastDelegate et des fonctions template spécialisées pour les fonctions membres c'est à dire les classes FastDelegate2 et FastDelegate3 ou bien 4 si je me rappelle bien, pas celles destinées aux autres fonctions c'est à dire les classes FastDelegate0 et 6, mais, de toute façon, j'avais trop de spécialisations différentes et il fallait que je revoie mon code)

    Enfin non au fait, j'aurai eu le même problème, ne connaissant pas le type de base à la création du delegate. (sauf si je force son passage par une macro)

    Soit!

    J'ai résolu le problème avec une macro.

    Je passe donc en résolu.
    Dernière modification par Invité ; 01/10/2014 à 21h52.

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

Discussions similaires

  1. [AC-2007] Objets non reconnus lors du passage Access 97 à Access 2007
    Par TheOutsider dans le forum Modélisation
    Réponses: 3
    Dernier message: 15/04/2015, 22h49
  2. Message d'erreur lors d'utilisation d'un Objet
    Par dirty_boy dans le forum Langage
    Réponses: 3
    Dernier message: 28/10/2005, 16h16
  3. Réponses: 20
    Dernier message: 23/09/2005, 13h50
  4. Masquer une forme lors du passage de souris
    Par gilles641 dans le forum Langage
    Réponses: 7
    Dernier message: 15/07/2005, 17h07
  5. probleme lors du passage de paramètre
    Par maxmj dans le forum ASP
    Réponses: 4
    Dernier message: 18/11/2003, 00h15

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