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 :

Changer un type en un autre en compilation.


Sujet :

Langage C++

  1. #21
    Invité
    Invité(e)
    Par défaut
    Voilà j'ai fini mon systè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
    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
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
     
    //#include "application.h"
    #include <fstream>
    #include "odfaeg/Core/fastDelegate.h"
    #include <functional>
    #include <iostream>
    #include <tuple>
    #include <utility>
    #include <memory>
    #include "../include/odfaeg/Core/erreur.h"
    /**
    *  \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, int I>
    struct Placeholder {
        static constexpr int getI() {
            return I;
        }
        void operator=(const T& t) {
            this->t = t;
        }
        T& get() {
           return t;
        }
        static constexpr int i = I;
        using type = T;
        T t;
    };
    template <class T>
    using _1 = Placeholder<T, 1>;
    template <class T>
    using _2 = Placeholder<T, 2>;
    template <typename T>
    struct is_placeholder {
        static constexpr bool value = false;
    };
    template <typename T, int I>
    struct is_placeholder<Placeholder<T, I>> {
        static constexpr bool value = true;
    };
    template <typename T, int I>
    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 Placeholder<T, I>& 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, I>> 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; }
    };
    template<class T>
    struct IRefVal<T, 0> {
        /**\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, 0>> 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, 0> {
        /**
        *\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, 0>> 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, 0> {
        /**\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, 0>> clone() const
    	{ return std::make_unique<Val>(*this); }
    private:
    	T val; /**> T val : keep the value of the wrapper.*/
    };
    template <class T, int I>
    struct PlaceholdersWrapper : IRefVal<T, I> {
         PlaceholdersWrapper (Placeholder<T, I> pl) : pl(pl) {
     
         }
         Placeholder<T, I>& get() {
             return pl;
         }
         std::unique_ptr<IRefVal<T, I>> clone() const
    	 { return std::make_unique<PlaceholdersWrapper<T, I>>(*this); }
    private :
         Placeholder<T, I> pl;
    };
    /**
    *  \file  fastDelegate.h
    *  \class Ref
    *  \brief Warp a pointer.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T, int I>
    struct RefVal {
        RefVal() = default;
        RefVal(const Placeholder<T, I>& pl)
    	: rv(std::make_unique<PlaceholdersWrapper<T, I>>(pl))
    	{}
    	RefVal(const RefVal& rhs) {
    	    rv = rhs.rv->clone();
    	}
    	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.
            */
    	Placeholder<T, I>& get() const
    	{ return rv->get(); }
    private:
    	std::unique_ptr<IRefVal<T, I>> rv; /**> a pointer to the generic wrapper interface.*/
    };
    template<class T>
    struct RefVal<T, 0> {
        RefVal() = default;
        /**
        * \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))
    	{}
    	RefVal(const RefVal& rhs) {
    	    rv = rhs.rv->clone();
    	}
    	RefVal(const RefVal&& rhs) {
            rv = rhs.rv->clone();
    	}
        template <int I>
    	RefVal& operator=(Placeholder<T, I>&& rhs) {
            *this = RefVal(rhs.get());
            return *this;
    	}
        RefVal& operator=(const RefVal& rhs)
    	{ rv=rhs.rv->clone(); return *this; }
    	RefVal& operator=(const RefVal&& rhs)
    	{ rv=rhs.rv->clone(); return *this; }
    	T& get() {
    	    return rv->get();
    	}
    	/** \fn T& get() const
            *   \brief get the wrapper.
            *   \return a unique pointer to the generic wrapper interface.
            */
    private:
    	std::unique_ptr<IRefVal<T, 0>> 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 ToStoreImpl1
    { 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 ToStoreImpl1<std::reference_wrapper<T>>
    { using type = T; };
    template<class T, int I>
    struct ToStoreImpl1<Placeholder<T, I>>
    { 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 ToStore1
    	: ToStoreImpl1<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_f = typename
    	ToStore1<T>::type;
    //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 ToStoreImpl2
    { 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 ToStoreImpl2<std::reference_wrapper<T>>
    { using type = T; };
    template<class T, int I>
    struct ToStoreImpl2<Placeholder<T, I>>
    { using type = Placeholder<T, I>; };
     
    /**
    *  \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 ToStore2
    	: ToStoreImpl2<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
    	ToStore2<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 odfaeg::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 odfaeg::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;
    	}
    };
    template <class... ArgT>
    struct RefValPl {
    };
    template <class ArgH, class... ArgT>
    struct RefValPl <ArgH, ArgT...>{
        template<class... ArgU>
    	RefValPl(ArgU&&... arg) :
    		param(std::forward<ArgU>(arg)...)
    	{
    	    std::cout<<"non place holder"<<std::endl;
    	}
    	template <typename... ArgU>
    	void setParams(ArgU&&... args) {
            param = std::make_tuple(std::forward<ArgU>(args)...);
    	}
    	std::tuple<RefVal<ArgH, 0>, ArgT...> getParams() {
    	    return param;
    	}
        private :
        std::tuple<RefVal<ArgH, 0>, ArgT...> param;
    };
    template <template <class, int> class P, class T, int I, class... ArgT>
    struct RefValPl<P<T, I>, ArgT...> {
        template<class... ArgU>
    	RefValPl(ArgU&&... arg) :
    		 placeholders(std::forward<ArgU>(arg)...)
    	{
    	    std::cout<<"place holder"<<std::endl;
    	}
    	template <typename... ArgU>
    	void setParams(ArgU&&... args) {
    	    std::tuple<ArgU...> tp = std::make_tuple(std::forward<ArgU>(args)...);
            changeParams(std::make_index_sequence<sizeof...(ArgT)+1>(), tp);
    	}
    	std::tuple<RefVal<typename P<T, I>::type, 0>, ArgT...> getParams() {
    	   return param;
    	}
        private :
        template <std::size_t... IND, typename... ArgU>
        void changeParams (std::index_sequence<IND...>, std::tuple<ArgU...> tp) {
            param = std::make_tuple(std::get<IND>(tp)...);
        }
        std::tuple<RefVal<typename P<T, I>::type, P<T, I>::i>, ArgT...> placeholders;
        std::tuple<RefVal<typename P<T, I>::type, 0>, ArgT...> param;
    };
    template <class ArgH>
    struct RefValPl<ArgH> {
        template<class... ArgU>
    	RefValPl(ArgU&&... arg) :
    		param(std::forward<ArgU>(arg)...)
    	{
    	    std::cout<<"non place holder"<<std::endl;
    	}
    	template <typename... ArgU>
    	void setParams(ArgU&&... args) {
            param = std::make_tuple(std::forward<ArgU>(args)...);
    	}
    	std::tuple<RefVal<ArgH, 0>> getParams() {
    	    return param;
    	}
        private :
        std::tuple<RefVal<ArgH, 0>> param;
    };
    template <template <class, int> class P, class T, int I>
    struct RefValPl<P<T, I>> {
        template<class... ArgU>
    	RefValPl(ArgU&&... arg) :
    		 placeholders(std::forward<ArgU>(arg)...)
    	{
    	    std::cout<<"place holder"<<std::endl;
    	}
    	template <typename... ArgU>
    	void setParams(ArgU&&... args) {
    	    std::tuple<ArgU...> tp = std::make_tuple(std::forward<ArgU>(args)...);
            changeParams(std::make_index_sequence<1>(), tp);
    	}
    	std::tuple<RefVal<typename P<T, I>::type, 0>> getParams() {
    	   return param;
    	}
        private :
        template <std::size_t... IND, typename... ArgU>
        void changeParams (std::index_sequence<IND...>, std::tuple<ArgU...> tp) {
            param = std::make_tuple(std::get<IND>(tp)...);
        }
        std::tuple<RefVal<typename P<T, I>::type, P<T, I>::i>> placeholders;
        std::tuple<RefVal<typename P<T, I>::type, 0>> param;
    };
    /**
    *  \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> , RefValPl<ToStore_t<ArgT>...> {
        /** \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) :
    	    RefValPl<ToStore_t<ArgT>...>(std::forward<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.
        */
        template <typename... ArgU>
    	void setParams(ArgU&&... args) {
    	    RefValPl<ToStore_t<ArgT>...>::setParams(std::forward<ArgU>(args)...);
    	}
    	R operator()()
    	{
    	    param = RefValPl<ToStore_t<ArgT>...>::getParams();
    	    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.
        */
     
     
    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()...); }
    	DynamicFunction<R(ToStore_f<ArgT>&...)> func; /**> a functor whith hold the pointer to a callback function.*/
    	std::tuple<RefVal<ToStore_f<ArgT>, 0>...> 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, 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... ArgT, class... ArgV>
    	void setParams(ArgV&&... arg)
    	{
    		using DynamicType =
    			FastDelegateImpl<R, ArgT...>*;
    		if (dynamic_cast<DynamicType>(delegate.get()))
               dynamic_cast<DynamicType>(delegate.get())->setParams(std::forward<ArgV>(arg)...);
            else
                throw odfaeg::Erreur(0, "Bad cast : you've passed a pointer to an object of a derived type as functor argument to the constructor,\n"
                             "which is not compatible with an argument of a base type passed to setParams!\n"
                             "Make a static cast from the derived object to the base object type when passing the argument to the constructor.\n"
                             "Exemple : FastDelegate<void> fd(ptrfunc, static_cast<Base*>(new Derived()); Base* b = &derived; fd.setParams(b)", 1);
    	}
    private:
    	std::unique_ptr<Delegate<R>> delegate; /**> holds the pointer to the generic delegate.*/
    };
    void f (int i, int j) {
        std::cout<<"i : "<<i<<" j : "<<j<<std::endl;
    }
    void f2 (int i) {
        std::cout<<"i : "<<i<<std::endl;
    }
    int main (int argv, char* argc[]) {
        FastDelegate<void> fd(&f,0, 1);
        fd.setParams<int, int>(1, 2);
        fd();
        FastDelegate<void> fdpl(&f, 3, _2<int>());
        fdpl.setParams<int, _2<int>>(3, 4);
        fdpl();  
    }

    Par contre j'arrive pas à faire deux std::get imbriqué comme ceci :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::get<std::get<P<T, I>::i(placeholders)>(tp);

    Pourtant, c'est bien une constexpr i .... et il y a bien une version constexpr de std::get..., je comprend pas pourquoi il veut pas compiler.

  2. #22
    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
    Oo ça ressemble pas à un système de placeholder l'utilisation que tu en fais. Quel intérêt de mettre un placeholder si tu dois utiliser un setParam avec l'ensemble des paramètres avant de faire l'appel ? Ça sert à rien. L'intérêt des placeholders c'est qu'ils prennent le i-iemme paramètre lors de l'appel (donc de l'opérateur operator()) là où tu as indiqué le placeholder i.

    Ton main devrait ressembler à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int main (int argv, char* argc[]) {
        FastDelegate<void> fdpl(&f, 3, _1<int>());;
        fdpl(4);  
    }
    Du moins si tu veux que les gens habitués aux placeholders puissent utiliser un minimum ton code.

    Un appel à une fonction constexpr n'est pas systématiquement une expression constante, pour ça il faut qu'elle puisse être évaluée à la compilation. Donnes l'erreur (en entier avec toutes les notes) elle contient surement la réponse.

  3. #23
    Invité
    Invité(e)
    Par défaut
    Bah justement le problème c'est que mes 2 tuples n'ont pas le même nombre d'éléments, et je ne sais pas comment faire pour changer les éléments n°i d'un tuple. (Ne changer que les paramètres pour les placeholders quoi....)

  4. #24
    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
    Et si tu regardais ce que j'ai proposé comme code ? Etant donné qu'il marche, ça ne me semble pas absurde comme idée ...

  5. #25
    Invité
    Invité(e)
    Par défaut
    J'ai essayé ceci mais ça mène à un crash. :/

    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
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
     
    /**
    *  \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, int I>
    struct Placeholder {
        Placeholder() {
        }
        constexpr int getI() {
            return I;
        }
        void operator=(const T& t) {
            this->t = t;
        }
        T& get() {
           return t;
        }
        static const int i = I;
        using type = T;
        T t;
    };
    template <class T>
    using _1 = Placeholder<T, 1>;
    template <class T>
    using _2 = Placeholder<T, 2>;
    template <typename T>
    struct is_placeholder {
        static constexpr bool value = false;
    };
    template <typename T, int I>
    struct is_placeholder<Placeholder<T, I>> {
        static constexpr bool value = true;
    };
    template <typename T, int I>
    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 const Placeholder<T, I>& get() const =0;
    	/**\fn std::unique_ptr<IRefVal<T>> clone() const = 0;
            *  \brief copy the wrapper.
            *  \return the copied wrapper.*/
    	virtual std::unique_ptr<IRefVal<T, I>> clone() const = 0;
    	/**\fn destructor*/
    	virtual ~IRefVal(){}
    };
    template<class T>
    struct IRefVal<T, 0> {
        /**\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, 0>> clone() const = 0;
    	/**\fn destructor*/
    	virtual ~IRefVal(){}
    };
    /**
    *  \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, 0> {
        /**
        *\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, 0>> 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, 0> {
        /**\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, 0>> clone() const
    	{ return std::make_unique<Val>(*this); }
    private:
    	T val; /**> T val : keep the value of the wrapper.*/
    };
    template <class T, int I>
    struct PlaceholdersWrapper : IRefVal<T, I> {
         PlaceholdersWrapper (Placeholder<T, I> pl) : pl(pl) {
     
         }
         const Placeholder<T, I>& get() const {
             return pl;
         }
         std::unique_ptr<IRefVal<T, I>> clone() const
    	 { return std::make_unique<PlaceholdersWrapper<T, I>>(*this); }
    private :
         Placeholder<T, I> pl;
    };
    /**
    *  \file  fastDelegate.h
    *  \class Ref
    *  \brief Warp a pointer.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T, int I>
    struct RefVal {
        RefVal() = default;
        RefVal(const Placeholder<T, I>& pl)
    	: rv(std::make_unique<PlaceholdersWrapper<T, I>>(pl))
    	{}
    	RefVal(const RefVal& rhs) {
    	    rv = rhs.rv->clone();
    	}
    	RefVal(const RefVal&& rhs) {
    	    rv = rhs.rv->clone();
    	}
    	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.
            */
    	const Placeholder<T, I>& get() const
    	{ return rv->get(); }
    private:
    	std::unique_ptr<IRefVal<T, I>> rv; /**> a pointer to the generic wrapper interface.*/
    };
    template<class T>
    struct RefVal<T, 0> {
        RefVal() = default;
        /**
        * \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))
    	{}
    	RefVal(const RefVal& rhs) {
    	    rv = rhs.rv->clone();
    	}
    	RefVal(const RefVal&& rhs) {
    	    rv = rhs.rv->clone();
    	}
    	/**
        * \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))
    	{}
    	RefVal& operator=(const RefVal& rhs)
    	{ rv=rhs.rv->clone(); return *this; }
    	RefVal& operator=(const RefVal&& rhs)
    	{ rv=rhs.rv->clone(); return *this; }
    	T& get() {
    	    return rv->get();
    	}
    	/** \fn T& get() const
            *   \brief get the wrapper.
            *   \return a unique pointer to the generic wrapper interface.
            */
    private:
    	std::unique_ptr<IRefVal<T, 0>> 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 ToStoreImpl1
    { 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 ToStoreImpl1<std::reference_wrapper<T>>
    { using type = T; };
    template<class T, int I>
    struct ToStoreImpl1<Placeholder<T, I>>
    { 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 ToStore1
    	: ToStoreImpl1<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_f = typename
    	ToStore1<T>::type;
    //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 ToStoreImpl2
    { 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 ToStoreImpl2<std::reference_wrapper<T>>
    { using type = T; };
    template<class T, int I>
    struct ToStoreImpl2<Placeholder<T, I>>
    { using type = Placeholder<T, I>; };
     
    /**
    *  \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 ToStore2
    	: ToStoreImpl2<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
    	ToStore2<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 odfaeg::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 odfaeg::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;
    	}
    };
    template <class Arg>
    struct RefValPl {
        template<class ArgU>
    	RefValPl(ArgU&& arg)
    	{
    	    std::cout<<"non place holder"<<std::endl;
    	}
    	template <typename ArgU>
    	void setParams(ArgU&& arg) {
            param = RefVal<typename std::remove_reference<ArgU>::type, 0>(std::forward<ArgU>(arg));
    	}
    	template <int I>
    	constexpr int getPlaceHolder() {
    	    return I;
    	}
    	RefVal<Arg, 0>& getParams() {
    	    return param;
    	}
        private :
        RefVal<Arg, 0> param;
    };
    template <template <class, int> class P, class T, int I>
    struct RefValPl<P<T, I>> {
        template<class ArgU>
    	RefValPl(ArgU&& arg) :
    		 placeholders(std::forward<ArgU>(arg))
    	{
    	    std::cout<<"place holder"<<std::endl;
    	}
    	template <typename ArgU, typename... TP>
    	void setParams(ArgU&& arg, TP...) {
    	     param = RefVal<typename std::remove_reference<ArgU>::type, 0>(std::forward<ArgU>(arg));
    	}
    	RefVal<typename P<T, I>::type, 0>& getParams() {
    	   return param;
    	}
    	template <int IND>
    	constexpr int getPlaceHolder() {
    	    placeholders.get().getI();
    	}
        private :
        RefVal<typename P<T, I>::type, P<T, I>::i> placeholders;
        RefVal<typename P<T, I>::type, 0> param;
    };
    /**
    *  \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.
        */
        template <typename... ArgU>
    	void setParams(ArgU&&... args) {
    	    std::tuple<ArgU...> param = std::make_tuple(std::forward<ArgU>(args)...);
    	    changeParams(param);
    	}
    	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.
        */
     
     
    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 = 0,  typename... TP>
        inline typename std::enable_if<I == sizeof...(TP), void>::type
    	changeParams(std::tuple<TP...> param) {
     
    	}
    	template<std::size_t I = 0, typename... TP>
    	inline typename std::enable_if<I < sizeof...(TP), void>::type
        changeParams(std::tuple<TP...> prms) {
             //constexpr const int i = std::get<I>(param).getPlaceHolder<I>();
    	     std::get<I>(param).setParams(std::forward<decltype(std::get<I>(prms))>(std::get<I>(prms)));
    	     changeParams<I+1, TP...>(prms);
    	}
    	template<std::size_t... I>
    	R call(std::index_sequence<I...>)
    	{ return func(std::get<I>(param).getParams().get()...); }
    	DynamicFunction<R(ToStore_f<ArgT>&...)> func; /**> a functor whith hold the pointer to a callback function.*/
    	std::tuple<RefValPl<ToStore_t<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, 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... ArgT, class... ArgV>
    	void setParams(ArgV&&... args)
    	{
    		using DynamicType =
    			FastDelegateImpl<R, ArgT...>*;
    		if (dynamic_cast<DynamicType>(delegate.get()))
               dynamic_cast<DynamicType>(delegate.get())->setParams(std::forward<ArgV>(args)...);
            else
                throw odfaeg::Erreur(0, "Bad cast : you've passed a pointer to an object of a derived type as functor argument to the constructor,\n"
                             "which is not compatible with an argument of a base type passed to setParams!\n"
                             "Make a static cast from the derived object to the base object type when passing the argument to the constructor.\n"
                             "Exemple : FastDelegate<void> fd(ptrfunc, static_cast<Base*>(new Derived()); Base* b = &derived; fd.setParams(b)", 1);
    	}
    private:
    	std::unique_ptr<Delegate<R>> delegate; /**> holds the pointer to the generic delegate.*/
    };
    void f (int i, int j) {
        std::cout<<"i : "<<i<<" j : "<<j<<std::endl;
    }
    void f2 (int i) {
        std::cout<<"i : "<<i<<std::endl;
    }
    int main (int argv, char* argc[]) {
        FastDelegate<void> fd(&f, _1<int>(), 1);
        fd.setParams<_1<int>, int>(2);
        fd();
        return 0;


    Toujours obligé de passer les 2 paramètres...

    Ton code ne gère pas l'ordre des placeholders il me semble, moi je voudrais juste retourner une constexpr sur le numéro du placeholder pour récupérer la bonne position dans le tuple, mais, je sais pas comment faire pour récupérer cette constexpr. :/

  6. #26
    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
    Qu’appels-tu l'ordre des placeholder ?

  7. #27
    Invité
    Invité(e)
    Par défaut
    Quelque chose comme ceci :

    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
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
     
    #include "application.h"
    #include <fstream>
    #include "odfaeg/Core/fastDelegate.h"
    #include <functional>
    #include <iostream>
    #include <tuple>
    #include <utility>
    #include <memory>
    #include "../include/odfaeg/Core/erreur.h"
    /**
    *  \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, std::size_t I>
    struct Placeholder {
        static const std::size_t i = I;
        using type = T;
    };
    template <class T>
    using _1 = Placeholder<T, 1>;
    template <class T>
    using _2 = Placeholder<T, 2>;
    template <typename T>
    struct is_placeholder {
        static constexpr bool value = false;
    };
    template <typename T, std::size_t I>
    struct is_placeholder<Placeholder<T, I>> {
        static constexpr bool value = true;
    };
    template <typename T, std::size_t I>
    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 const Placeholder<T, I>& get() const =0;
    	/**\fn std::unique_ptr<IRefVal<T>> clone() const = 0;
            *  \brief copy the wrapper.
            *  \return the copied wrapper.*/
    	virtual std::unique_ptr<IRefVal<T, I>> clone() const = 0;
    	/**\fn destructor*/
    	virtual ~IRefVal(){}
    };
    template<class T>
    struct IRefVal<T, 0> {
        /**\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, 0>> clone() const = 0;
    	/**\fn destructor*/
    	virtual ~IRefVal(){}
    };
    /**
    *  \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, 0> {
        /**
        *\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, 0>> 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, 0> {
        /**\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, 0>> clone() const
    	{ return std::make_unique<Val>(*this); }
    private:
    	T val; /**> T val : keep the value of the wrapper.*/
    };
    template <class T, int I>
    struct PlaceholdersWrapper : IRefVal<T, I> {
         PlaceholdersWrapper (Placeholder<T, I> pl) : pl(pl) {
     
         }
         const Placeholder<T, I>& get() const {
             return pl;
         }
         std::unique_ptr<IRefVal<T, I>> clone() const
    	 { return std::make_unique<PlaceholdersWrapper<T, I>>(*this); }
    private :
         Placeholder<T, I> pl;
    };
    /**
    *  \file  fastDelegate.h
    *  \class Ref
    *  \brief Warp a pointer.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    template<class T, std::size_t I>
    struct RefVal {
        RefVal() = default;
        RefVal(const Placeholder<T, I>& pl)
    	: rv(std::make_unique<PlaceholdersWrapper<T, I>>(pl))
    	{}
    	RefVal(const RefVal& rhs) {
    	    rv = rhs.rv->clone();
    	}
    	RefVal(const RefVal&& rhs) {
    	    rv = rhs.rv->clone();
    	}
    	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.
            */
    	const Placeholder<T, I>& get() const
    	{ return rv->get(); }
    private:
    	std::unique_ptr<IRefVal<T, I>> rv; /**> a pointer to the generic wrapper interface.*/
    };
    template<class T>
    struct RefVal<T, 0> {
        RefVal() = default;
        /**
        * \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))
    	{}
    	RefVal(const RefVal& rhs) {
    	    rv = rhs.rv->clone();
    	}
    	RefVal(const RefVal&& rhs) {
    	    rv = rhs.rv->clone();
    	}
    	/**
        * \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))
    	{}
    	RefVal& operator=(const RefVal& rhs)
    	{ rv=rhs.rv->clone(); return *this; }
    	RefVal& operator=(const RefVal&& rhs)
    	{ rv=rhs.rv->clone(); return *this; }
    	T& get() {
    	    return rv->get();
    	}
    	/** \fn T& get() const
            *   \brief get the wrapper.
            *   \return a unique pointer to the generic wrapper interface.
            */
    private:
    	std::unique_ptr<IRefVal<T, 0>> 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 ToStoreImpl1
    { 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 ToStoreImpl1<std::reference_wrapper<T>>
    { using type = T; };
    template<class T, std::size_t I>
    struct ToStoreImpl1<Placeholder<T, I>>
    { 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 ToStore1
    	: ToStoreImpl1<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_f = typename
    	ToStore1<T>::type;
    //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 ToStoreImpl2
    { 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 ToStoreImpl2<std::reference_wrapper<T>>
    { using type = T; };
    template<class T, std::size_t I>
    struct ToStoreImpl2<Placeholder<T, I>>
    { using type = Placeholder<T, I>; };
     
    /**
    *  \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 ToStore2
    	: ToStoreImpl2<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
    	ToStore2<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 odfaeg::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 odfaeg::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;
    	}
    };
    template <class Arg>
    struct RefValPl {
        using type = Arg;
        template<class ArgU>
    	RefValPl(ArgU&& arg) :
        param (std::forward<ArgU>(arg))
    	{
    	    std::cout<<"non place holder"<<std::endl;
    	}
    	template <typename ArgU>
    	void setParams(ArgU&& arg) {
            param = RefVal<ToStore_f<ArgU>, 0>(std::forward<ArgU>(arg));
    	}
    	template <std::size_t I>
    	constexpr std::size_t getPosition() {
    	    return I;
    	}
    	RefVal<Arg, 0>& getParams() {
    	    return param;
    	}
        private :
        RefVal<Arg, 0> param;
     
    };
    template <template <class, std::size_t> class P, class T, std::size_t I>
    struct RefValPl<P<T, I>> {
        template<class ArgU>
    	RefValPl(ArgU&& arg) :
    		 placeholders(std::forward<ArgU>(arg))
    	{
    	    std::cout<<"place holder"<<std::endl;
    	}
    	template <typename ArgU>
    	void setParams(ArgU&& arg) {
    	     param = RefVal<typename P<T, I>::type, 0>(std::forward<ArgU>(arg));
    	}
    	RefVal<typename P<T, I>::type, 0>& getParams() {
    	   return param;
    	}
    	template <std::size_t IND>
    	inline constexpr std::size_t getPosition() {
    	    P<T, I>::i;
    	}
    	constexpr T getType() {
    	    return P<T, I>::type;
    	}
        private :
        RefVal<typename P<T, I>::type, P<T, I>::i> placeholders;
        RefVal<typename P<T, I>::type, 0> param;
    };
    /**
    *  \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.
        */
        template <typename... ArgU>
    	void setParams(ArgU&&... args) {
    	    std::tuple<ArgU...> param = std::make_tuple(std::forward<ArgU>(args)...);
    	    changeParams(param);
    	}
    	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.
        */
     
     
    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 = 0,  typename... TP>
        inline typename std::enable_if<I == sizeof...(TP), void>::type
    	changeParams(std::tuple<TP...> param) {
     
    	}
    	template<std::size_t I = 0, typename... TP>
    	inline typename std::enable_if<I < sizeof...(TP), void>::type
        constexpr changeParams(std::tuple<TP...> prms) {
             std::get<I>(param).setParams(
             std::forward<decltype(std::get<std::get<I>(param).getPosition<I>()>(prms))>
            (std::get<std::get<I>(param).getPosition<I>()>(prms)));
    	     changeParams<I+1, TP...>(prms);
    	}
    	template<std::size_t... I>
    	R call(std::index_sequence<I...>)
    	{ return func(std::get<I>(param).getParams().get()...); }
    	DynamicFunction<R(ToStore_f<ArgT>&...)> func; /**> a functor whith hold the pointer to a callback function.*/
    	std::tuple<RefValPl<ToStore_t<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, 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... ArgT, class... ArgV>
    	void setParams(ArgV&&... args)
    	{
    		using DynamicType =
    			FastDelegateImpl<R, ArgT...>*;
    		if (dynamic_cast<DynamicType>(delegate.get()))
               dynamic_cast<DynamicType>(delegate.get())->setParams(std::forward<ArgV>(args)...);
            else
                throw odfaeg::Erreur(0, "Bad cast : you've passed a pointer to an object of a derived type as functor argument to the constructor,\n"
                             "which is not compatible with an argument of a base type passed to setParams!\n"
                             "Make a static cast from the derived object to the base object type when passing the argument to the constructor.\n"
                             "Exemple : FastDelegate<void> fd(ptrfunc, static_cast<Base*>(new Derived()); Base* b = &derived; fd.setParams(b)", 1);
    	}
    private:
    	std::unique_ptr<Delegate<R>> delegate; /**> holds the pointer to the generic delegate.*/
    };
    void f (int i, int j) {
        std::cout<<"i : "<<i<<" j : "<<j<<std::endl;
    }
    void f2 (int i) {
        std::cout<<"i : "<<i<<std::endl;
    }
    int main (int argv, char* argc[]) {
        FastDelegate<void> fd(&f, _1<int>(), 1);
        fd.setParams<_1<int>, int>(2);
        fd();
     }

    J'ai résolu le problème du crash par contre dès que je veux récupérer la constexpr j'ai une erreur à cette ligne :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    std::forward<decltype(std::get<std::get<I>(param).getPosition<I>()>(prms))>
            (std::get<std::get<I>(param).getPosition<I>()>(prms)));

    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 member function ‘constexpr std::size_t RefValPl<P<T, I> >::getPosition() const’:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|530|warning: no return statement in function returning non-void [-Wreturn-type]|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp||In instantiation of ‘constexpr typename std::enable_if<(I < sizeof... (TP)), void>::type FastDelegateImpl<R, ArgT>::changeParams(std::tuple<_Args2 ...>) const [with long unsigned int I = 0ul; TP = {int}; R = void; ArgT = {Placeholder<int, 1ul>, int}; typename std::enable_if<(I < sizeof... (TP)), void>::type = void]’:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|569|required from ‘void FastDelegateImpl<R, ArgT>::setParams(ArgU&& ...) [with ArgU = {int}; R = void; ArgT = {Placeholder<int, 1ul>, int}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|680|required from ‘void FastDelegate<R>::setParams(ArgV&& ...) [with ArgT = {Placeholder<int, 1ul>, int}; ArgV = {int}; R = void]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|698|required from here|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|596|error: invalid operands of types ‘<unresolved overloaded function type>’ andlong unsigned int’ to binary ‘operator<’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: invalid operands of types ‘<unresolved overloaded function type>’ andlong unsigned int’ to binary ‘operator<’|
    ||=== Build failed: 2 error(s), 5 warning(s) (0 minute(s), 5 second(s)) ===|
    Par exemple si j'ai deux placeholders _1<int> ça va passer deux fois la valeur de l'élément 0 du tuple que je passe à setParams et la remplacer partout là ou j'ai le type _1<int>() dans le 1er tuple, pareil pour _2<int>, etc...

    Bref std::bind permet de faire cela.

  8. #28
    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 que je te propose est l'unique solution à ton problème.

    La problématique est de rendre fonctionnel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    odfaeg::delegate<void> func(foo,odfaeg::ph<0,int>());
    func(1);
    Remontons la pile d'appel pour voir ce qu'il faut modifier :
    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
     
    struct delegate {
    	template<class F, class... Arg>
    	delegate(F&& f, Arg&&... arg) :
    		data(std::make_unique<delegate_impl<
    				R,to_store_t<Arg>...
    			>>
    			(std::forward<F>(f),std::forward<Arg>(arg)...)
    		)
    	{}
     
    	template<class... Arg>
    	R operator()() const
    	{ return (*data)(); }
    };
    L'appel au constructeur est toujours bon si la classe de trait l'est, il faut donc l'adapter à notre type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    template<size_t I, class T>
    struct to_store_impl<ph<I,T>>
    { using type = T; };
    L'opérateur d'appel n'est pas bon, modifions le :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct delegate {
    	template<class... Arg>
    	R operator()(Arg&&... arg) const
    	{ return (*data)(); }
    };
    Cette fois l'appel est bon, il reste à savoir comment modifier l'implémentation, mais pour ça il faut encore remonter la pile :
    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
     
    struct delegate_impl : delegate_i<R>
    {
    	template<class F, class... ArgU>
    	delegate_impl(F&& f, ArgU&&... arg)
    		: func(std::forward<F>(f))
    		, param(std::forward<ArgU>(arg)...)
    	{}
     
    	R operator()() const
    	{ return call(std::make_index_sequence<sizeof...(ArgT)>()); }
     
    private:
    	template<std::size_t... I>
    	R call(std::index_sequence<I...>) const
    	{
    		return func(
    			std::get<I>(param)
    			.get()...
    		);
    	}
    };
    Le constructeur est bon, par contre l'opérateur d'appel toujours pas, et il est cette fois impossible de le template (fonction virtuelle). On a donc besoin d'un type qui peut convenir pour n'importe quoi : void*. D'où :
    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
     
    #define FUN_PARAM void* p0 =nullptr, void* p1 =nullptr, void* p2 =nullptr, void* p3 =nullptr
    #define FWD_PARAM p0,p1,p2,p3
     
    struct delegate_impl : delegate_i<R>
    {
    	R operator()(FUN_PARAM) const
    	{ return call(std::make_index_sequence<sizeof...(ArgT)>(),FWD_PARAM); }
     
    private:
    	template<std::size_t... I, class... ArgU>
    	R call(std::index_sequence<I...>, ArgU&&... arg) const
    	{
    		return func(
    			std::get<I>(param)
    			.get(std::forward<ArgU>(arg)...)...
    		);
    	}
    };
    La limitation est donc le nombre de paramètre mis en place dans la macro. On fait bien entendu suivre l'ensemble à la fonction interne call (qui peut cette fois utiliser un paramètre template variadique) puis à get. On peut donc écrire l'implémentation du premier opérateur d'appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct delegate {
    	template<class... Arg>
    	R operator()(Arg&&... arg) const
    	{ return (*data)(&arg...); }
    };
    On continue ensuite de remonter la pile d'appel, get est modifié pour supporter plusieurs paramètres dans le code existant, avec un paramètre template variadique et la macro FUN_PARAM. Il ne manque qu'un élément, le placeholder. Il peut être stocké dans le type utilisé dans notre tuple, il doit donc hériter de ref_val_i :
    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
     
    template<size_t I, class T>
    struct ph : ref_val_i<T>
    {
    	std::unique_ptr<ref_val_i<T>> clone() const
    	{ return std::make_unique<ph>(*this); }
     
    	T& get(FUN_PARAM)
    	{
    		return *static_cast<T*>
    			(std::get<I>(std::make_tuple(FWD_PARAM)));
    	}
    };
     
    struct ref_val
    {
    	template<size_t I>
    	ref_val(ph<I,T>&&)
    		: rv(std::make_unique<ph<I,T>>())
    	{}
     
    	template<class... Arg>
    	T& get(Arg&&... arg) const
    	{ return rv->get(std::forward<Arg>(arg)...); }
    };
    Tu as ici le raisonnement complet qui conduit à cette implémentation, et il n'y a pas de décision alternative possible dans le raisonnement.

    Pour ton erreur, il doit te manquer un template ici : std::get<I>(param).template getPosition<I>()

  9. #29
    Invité
    Invité(e)
    Par défaut
    J'ai rajouté le template mais j'ai une autre erreur maintenant.

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    template<std::size_t I = 0, typename... TP>
    	inline typename std::enable_if<I < sizeof...(TP), void>::type
        changeParams(std::tuple<TP...> prms) {
             constexpr std::size_t i = std::get<I>(prms).template getPosition<I>();
             std::get<i>(param).setParams(
             std::forward<decltype(std::get<I>(prms))>
             (std::get<I>(prms)));
    	     changeParams<I+1, TP...>(prms);
    	}

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    template<std::size_t I = 0, typename... TP>
    	inline typename std::enable_if<I < sizeof...(TP), void>::type
        changeParams(std::tuple<TP...> prms) {
             constexpr std::size_t i = std::get<I>(prms).template getPosition<I>();
             std::get<i>(param).setParams(
             std::forward<decltype(std::get<I>(prms))>
             (std::get<I>(prms)));
    	     changeParams<I+1, TP...>(prms);
    	}

    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
     
    ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp||In instantiation of ‘constexpr typename std::enable_if<(I < sizeof... (TP)), void>::type FastDelegateImpl<R, ArgT>::changeParams(std::tuple<_Args2 ...>) const [with long unsigned int I = 0ul; TP = {int}; R = void; ArgT = {Placeholder<int, 1ul>, int}; typename std::enable_if<(I < sizeof... (TP)), void>::type = void]’:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|561|required from ‘void FastDelegateImpl<R, ArgT>::setParams(ArgU&& ...) [with ArgU = {int}; R = void; ArgT = {Placeholder<int, 1ul>, int}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|674|required from ‘void FastDelegate<R>::setParams(ArgV&& ...) [with ArgT = {Placeholder<int, 1ul>, int}; ArgV = {int}; R = void]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|692|required from here|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|587|error: request for member ‘getPosition<0ul>’ in ‘std::get<0ul, {int}>((* & prms))’, which is of non-class type ‘int’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|588|error: no matching function for call to ‘get(const std::tuple<RefValPl<Placeholder<int, 1ul> >, RefValPl<int> >&)’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|588|note: candidates are:|
    /usr/include/c++/4.9/utility|142|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)|
    /usr/include/c++/4.9/utility|142|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|147|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type&& std::get(std::pair<_Tp1, _Tp2>&&)|
    /usr/include/c++/4.9/utility|147|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|152|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr const typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(const std::pair<_Tp1, _Tp2>&)|
    /usr/include/c++/4.9/utility|152|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|158|note: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_T1, _T2>&)|
    /usr/include/c++/4.9/utility|158|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|163|note: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_T1, _T2>&)|
    /usr/include/c++/4.9/utility|163|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|168|note: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_T1, _T2>&&)|
    /usr/include/c++/4.9/utility|168|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|173|note: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_Up, _Tp>&)|
    /usr/include/c++/4.9/utility|173|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|178|note: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_Up, _Tp>&)|
    /usr/include/c++/4.9/utility|178|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|183|note: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_Up, _Tp>&&)|
    /usr/include/c++/4.9/utility|183|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/array|272|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp& std::get(std::array<_Tp, _Nm>&)|
    /usr/include/c++/4.9/array|272|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/array|281|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp&& std::get(std::array<_Tp, _Nm>&&)|
    /usr/include/c++/4.9/array|281|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/array|289|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr const _Tp& std::get(const std::array<_Tp, _Nm>&)|
    /usr/include/c++/4.9/array|289|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|756|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|756|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|764|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_c_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(const std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|764|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|772|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_r_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(std::tuple<_Args2 ...>&&)|
    /usr/include/c++/4.9/tuple|772|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|790|note: template<class _Tp, class ... _Types> constexpr _Tp& std::get(std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|790|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|796|note: template<class _Tp, class ... _Types> constexpr _Tp&& std::get(std::tuple<_Args2 ...>&&)|
    /usr/include/c++/4.9/tuple|796|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|802|note: template<class _Tp, class ... _Types> constexpr const _Tp& std::get(const std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|802|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp||In instantiation of ‘constexpr typename std::enable_if<(I < sizeof... (TP)), void>::type FastDelegateImpl<R, ArgT>::changeParams(std::tuple<_Args2 ...>) const [with long unsigned int I = 0ul; TP = {int}; R = void; ArgT = {int, Placeholder<int, 2ul>}; typename std::enable_if<(I < sizeof... (TP)), void>::type = void]’:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|561|required from ‘void FastDelegateImpl<R, ArgT>::setParams(ArgU&& ...) [with ArgU = {int}; R = void; ArgT = {int, Placeholder<int, 2ul>}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|674|required from ‘void FastDelegate<R>::setParams(ArgV&& ...) [with ArgT = {int, Placeholder<int, 2ul>}; ArgV = {int}; R = void]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|695|required from here|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|587|error: request for member ‘getPosition<0ul>’ in ‘std::get<0ul, {int}>((* & prms))’, which is of non-class type ‘int’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|588|error: no matching function for call to ‘get(const std::tuple<RefValPl<int>, RefValPl<Placeholder<int, 2ul> > >&)’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|588|note: candidates are:|
    /usr/include/c++/4.9/utility|142|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)|
    /usr/include/c++/4.9/utility|142|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|147|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type&& std::get(std::pair<_Tp1, _Tp2>&&)|
    /usr/include/c++/4.9/utility|147|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|152|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr const typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(const std::pair<_Tp1, _Tp2>&)|
    /usr/include/c++/4.9/utility|152|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|158|note: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_T1, _T2>&)|
    /usr/include/c++/4.9/utility|158|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|163|note: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_T1, _T2>&)|
    /usr/include/c++/4.9/utility|163|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|168|note: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_T1, _T2>&&)|
    /usr/include/c++/4.9/utility|168|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|173|note: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_Up, _Tp>&)|
    /usr/include/c++/4.9/utility|173|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|178|note: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_Up, _Tp>&)|
    /usr/include/c++/4.9/utility|178|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|183|note: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_Up, _Tp>&&)|
    /usr/include/c++/4.9/utility|183|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/array|272|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp& std::get(std::array<_Tp, _Nm>&)|
    /usr/include/c++/4.9/array|272|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/array|281|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp&& std::get(std::array<_Tp, _Nm>&&)|
    /usr/include/c++/4.9/array|281|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/array|289|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr const _Tp& std::get(const std::array<_Tp, _Nm>&)|
    /usr/include/c++/4.9/array|289|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|756|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|756|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|764|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_c_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(const std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|764|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|772|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_r_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(std::tuple<_Args2 ...>&&)|
    /usr/include/c++/4.9/tuple|772|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|790|note: template<class _Tp, class ... _Types> constexpr _Tp& std::get(std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|790|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|796|note: template<class _Tp, class ... _Types> constexpr _Tp&& std::get(std::tuple<_Args2 ...>&&)|
    /usr/include/c++/4.9/tuple|796|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|802|note: template<class _Tp, class ... _Types> constexpr const _Tp& std::get(const std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|802|note:   template argument deduction/substitution failed:|
    ||=== Build failed: 4 error(s), 8 warning(s) (0 minute(s), 5 second(s)) ===|

    N'y a t'il vraiment pas moyen de stocker l'index d'un tuple dans une structure, et de le récupérer par la suite ?

    J'ai toujours trouvé, que cette nouvelle classe n'est pas très pratique. (Surtout lorsqu'il faut remplacer des éléments dans un tuple, mais pas tous.)

    On a juste droit à std::make_sequence qui passe tout à une fonction, mais, aucun moyen d'itérer dessus de manière simple sans devoir utiliser des structures avec des tas de spécialisation.

  10. #30
    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
    L'erreur est clair pourtant ... ton get retourne un int et donc l'appel à la fonction getPosition est invalide.

  11. #31
    Invité
    Invité(e)
    Par défaut
    Ha oui en effet j'ai changé cela :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template<std::size_t I = 0, typename... TP>
    	inline typename std::enable_if<I < sizeof...(TP), void>::type
        changeParams(std::tuple<TP...> prms) {
            std::get<getIndex<I>()>(param).setParams(
            std::forward<decltype(std::get<getIndex<I>()>(prms))>
            (std::get<getIndex<I>()>(prms)));
    	    changeParams<I+1, TP...>(prms);
    	}

    Mais j'ai toujours des erreurs, hors que quand je remplace getIndex()<I>() par I ça passe mais c'est pas bon car, il me change pas le bonne élément dans le tuple param.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
     
    ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp||In instantiation of ‘typename std::enable_if<(I < sizeof... (TP)), void>::type FastDelegateImpl<R, ArgT>::changeParams(std::tuple<_Args2 ...>) [with long unsigned int I = 0ul; TP = {int}; R = void; ArgT = {int, Placeholder<int, 1ul>}; typename std::enable_if<(I < sizeof... (TP)), void>::type = void]’:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|572|required from ‘void FastDelegateImpl<R, ArgT>::setParams(ArgU&& ...) [with ArgU = {int}; R = void; ArgT = {int, Placeholder<int, 1ul>}]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|687|required from ‘void FastDelegate<R>::setParams(ArgV&& ...) [with ArgT = {int, Placeholder<int, 1ul>}; ArgV = {int}; R = void]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|705|required from here|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: no matching function for call to ‘get(std::tuple<RefValPl<int>, RefValPl<Placeholder<int, 1ul> > >&)’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|note: candidates are:|
    /usr/include/c++/4.9/utility|142|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)|
    /usr/include/c++/4.9/utility|142|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|603|note: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ is not usable as a constexpr function because:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|603|error: enclosing class of constexpr non-static member function ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ is not a literal type|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|550|note: ‘FastDelegateImpl<void, int, Placeholder<int, 1ul> >’ is not literal because:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|550|note:   ‘FastDelegateImpl<void, int, Placeholder<int, 1ul> >’ has a non-trivial destructor|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/utility|147|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type&& std::get(std::pair<_Tp1, _Tp2>&&)|
    /usr/include/c++/4.9/utility|147|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/utility|152|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr const typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(const std::pair<_Tp1, _Tp2>&)|
    /usr/include/c++/4.9/utility|152|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/utility|158|note: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_T1, _T2>&)|
    /usr/include/c++/4.9/utility|158|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|163|note: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_T1, _T2>&)|
    /usr/include/c++/4.9/utility|163|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|168|note: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_T1, _T2>&&)|
    /usr/include/c++/4.9/utility|168|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|173|note: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_Up, _Tp>&)|
    /usr/include/c++/4.9/utility|173|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|178|note: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_Up, _Tp>&)|
    /usr/include/c++/4.9/utility|178|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|183|note: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_Up, _Tp>&&)|
    /usr/include/c++/4.9/utility|183|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/array|272|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp& std::get(std::array<_Tp, _Nm>&)|
    /usr/include/c++/4.9/array|272|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/array|281|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp&& std::get(std::array<_Tp, _Nm>&&)|
    /usr/include/c++/4.9/array|281|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/array|289|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr const _Tp& std::get(const std::array<_Tp, _Nm>&)|
    /usr/include/c++/4.9/array|289|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|756|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|756|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|764|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_c_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(const std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|764|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|772|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_r_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(std::tuple<_Args2 ...>&&)|
    /usr/include/c++/4.9/tuple|772|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|597|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|790|note: template<class _Tp, class ... _Types> constexpr _Tp& std::get(std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|790|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|796|note: template<class _Tp, class ... _Types> constexpr _Tp&& std::get(std::tuple<_Args2 ...>&&)|
    /usr/include/c++/4.9/tuple|796|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|802|note: template<class _Tp, class ... _Types> constexpr const _Tp& std::get(const std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|802|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|error: no matching function for call to ‘get(std::tuple<int>&)’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|note: candidates are:|
    /usr/include/c++/4.9/utility|142|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)|
    /usr/include/c++/4.9/utility|142|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/utility|147|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type&& std::get(std::pair<_Tp1, _Tp2>&&)|
    /usr/include/c++/4.9/utility|147|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/utility|152|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr const typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(const std::pair<_Tp1, _Tp2>&)|
    /usr/include/c++/4.9/utility|152|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/utility|158|note: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_T1, _T2>&)|
    /usr/include/c++/4.9/utility|158|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|163|note: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_T1, _T2>&)|
    /usr/include/c++/4.9/utility|163|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|168|note: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_T1, _T2>&&)|
    /usr/include/c++/4.9/utility|168|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|173|note: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_Up, _Tp>&)|
    /usr/include/c++/4.9/utility|173|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|178|note: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_Up, _Tp>&)|
    /usr/include/c++/4.9/utility|178|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|183|note: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_Up, _Tp>&&)|
    /usr/include/c++/4.9/utility|183|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/array|272|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp& std::get(std::array<_Tp, _Nm>&)|
    /usr/include/c++/4.9/array|272|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/array|281|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp&& std::get(std::array<_Tp, _Nm>&&)|
    /usr/include/c++/4.9/array|281|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/array|289|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr const _Tp& std::get(const std::array<_Tp, _Nm>&)|
    /usr/include/c++/4.9/array|289|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|756|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|756|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|764|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_c_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(const std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|764|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|772|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_r_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(std::tuple<_Args2 ...>&&)|
    /usr/include/c++/4.9/tuple|772|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|598|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|790|note: template<class _Tp, class ... _Types> constexpr _Tp& std::get(std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|790|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|796|note: template<class _Tp, class ... _Types> constexpr _Tp&& std::get(std::tuple<_Args2 ...>&&)|
    /usr/include/c++/4.9/tuple|796|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|802|note: template<class _Tp, class ... _Types> constexpr const _Tp& std::get(const std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|802|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|error: no matching function for call to ‘get(std::tuple<int>&)’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|note: candidates are:|
    /usr/include/c++/4.9/utility|142|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)|
    /usr/include/c++/4.9/utility|142|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/utility|147|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type&& std::get(std::pair<_Tp1, _Tp2>&&)|
    /usr/include/c++/4.9/utility|147|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/utility|152|note: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr const typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(const std::pair<_Tp1, _Tp2>&)|
    /usr/include/c++/4.9/utility|152|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/utility|158|note: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_T1, _T2>&)|
    /usr/include/c++/4.9/utility|158|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|163|note: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_T1, _T2>&)|
    /usr/include/c++/4.9/utility|163|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|168|note: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_T1, _T2>&&)|
    /usr/include/c++/4.9/utility|168|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|173|note: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_Up, _Tp>&)|
    /usr/include/c++/4.9/utility|173|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|178|note: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_Up, _Tp>&)|
    /usr/include/c++/4.9/utility|178|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/utility|183|note: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_Up, _Tp>&&)|
    /usr/include/c++/4.9/utility|183|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/array|272|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp& std::get(std::array<_Tp, _Nm>&)|
    /usr/include/c++/4.9/array|272|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/array|281|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp&& std::get(std::array<_Tp, _Nm>&&)|
    /usr/include/c++/4.9/array|281|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/array|289|note: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr const _Tp& std::get(const std::array<_Tp, _Nm>&)|
    /usr/include/c++/4.9/array|289|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|756|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|756|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|764|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_c_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(const std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|764|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|772|note: template<long unsigned int __i, class ... _Elements> constexpr typename std::__add_r_ref<typename std::tuple_element<__i, std::tuple<_Args2 ...> >::type>::type std::get(std::tuple<_Args2 ...>&&)|
    /usr/include/c++/4.9/tuple|772|note:   template argument deduction/substitution failed:|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|error: ‘constexpr std::size_t FastDelegateImpl<R, ArgT>::getIndex() const [with long unsigned int I = 0ul; R = void; ArgT = {int, Placeholder<int, 1ul>}; std::size_t = long unsigned int]’ called in a constant expression|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|599|note: in template argument for type ‘long unsigned int’ |
    /usr/include/c++/4.9/tuple|790|note: template<class _Tp, class ... _Types> constexpr _Tp& std::get(std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|790|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|796|note: template<class _Tp, class ... _Types> constexpr _Tp&& std::get(std::tuple<_Args2 ...>&&)|
    /usr/include/c++/4.9/tuple|796|note:   template argument deduction/substitution failed:|
    /usr/include/c++/4.9/tuple|802|note: template<class _Tp, class ... _Types> constexpr const _Tp& std::get(const std::tuple<_Args2 ...>&)|
    /usr/include/c++/4.9/tuple|802|note:   template argument deduction/substitution failed:|
    ||=== Build failed: 31 error(s), 4 warning(s) (0 minute(s), 5 second(s)) ===|
    Bref, je pensais que ça marcherait mais, en fait non, il me semble que dès que j'ai une fonction constexpr il veut que tout le reste soit constexpr (c'est à dire également la fonction qui appelle la fonction consexpr, et les variables de la fonction, bref, tout quoi!)
    Je pensais qu'il me retournerait un literal de type std::size_t et le passe à std::get sans broncher, mais là il me chie carrément dessus.

    Ce qui est bien sûr fort gênant.

    Il semble qu'il n'y ai pas d'autres alternative possible, je vais essayer ta solution. (Dommage, je préférais celle avec les std::get imbriqués et les classes de politique au niveau syntaxique.)
    Dernière modification par Invité ; 12/10/2014 à 08h07.

  12. #32
    Invité
    Invité(e)
    Par défaut
    J'ai essayé ton code mais, il crash :

    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
     
    #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>
    #define FUN_PARAM void* p0 =nullptr, void* p1 =nullptr, void* p2 =nullptr, void* p3 =nullptr
    #define FWD_PARAM p0,p1,p2,p3
    /**
      *\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(FUN_PARAM) =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(FUN_PARAM)
    	{ 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(FUN_PARAM)
    	{ 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.*/
    };
    template<size_t I, class T>
    struct ph : IRefVal<T>
    {
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<ph>(*this); }
     
    	T& get(FUN_PARAM)
    	{
    		return *static_cast<T*>
    			(std::get<I>(std::make_tuple(FWD_PARAM)));
    	}
    };
    /**
    *  \file  fastDelegate.h
    *  \class Ref
    *  \brief Warp a pointer.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    /**
    *  \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 RefVal& rhs)
            *   \brief copy constructor, copy the wrapper with the right wrapper type.
            *   \param const RefVal& rhs : the wrapper to copy.
            */
    	template<size_t I>
    	RefVal(ph<I,T>&&)
    		: rv(std::make_unique<ph<I,T>>())
    	{}
    	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(); }
        template<class... Arg>
    	T& get(Arg&&... arg) const
    	{ return rv->get(std::forward<Arg>(arg)...); }
    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; };
    template<size_t I, class T>
    struct ToStoreImpl<ph<I,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);
    	}
    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()(FUN_PARAM) = 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()(FUN_PARAM)
    	{ return call(std::make_index_sequence<sizeof...(ArgT)>(), FWD_PARAM); }
    	/** \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, class... ArgU>
    	R call(std::index_sequence<I...>, ArgU&&... args) const
    	{ return func(std::get<I>(param).get()...); }
    	DynamicFunction<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.
            */
    	template<class... Arg>
    	R operator()(Arg&&... arg) const
    	{ return (*delegate)(&arg...); }
    	/**\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 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!", 5);
    	}
    private:
    	std::unique_ptr<Delegate<R>> delegate; /**> holds the pointer to the generic delegate.*/
    };
    }
    #endif

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int main (int argv, char* argc[]) {
        odfaeg::FastDelegate<void> fdpl(&f, 1, odfaeg::ph<0, int>());
        fdpl(3);
    }

    Voici ce que me dit le débogueur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #0 ??	std::_Function_handler<void (int&, int&), void (*)(int, int)>::_M_invoke(std::_Any_data const&, int&, int&) (__functor=..., __args#0=@0x76ef68: 1, __args#1=@0x0: <error reading variable>) (/usr/include/c++/4.9/functional:2039)
    #1 0x43c9e7	std::function<void (int&, int&)>::operator()(int&, int&) const(this=0x76ef18, __args#0=@0x76ef68: 1, __args#1=@0x0: <error reading variable>) (/usr/include/c++/4.9/functional:2439)
    #2 0x43c673	odfaeg::FastDelegateImpl<void, int, int>::call<0ul, 1ul, void*&, void*&, void*&, void*&>(this=0x76ef10) (/usr/local/include/odfaeg/Core/fastDelegate.h:445)
    #3 0x43bde9	odfaeg::FastDelegateImpl<void, int, int>::operator() (this=0x76ef10, p0=0x7fffffffe318, p1=0x0, p2=0x0, p3=0x0) (/usr/local/include/odfaeg/Core/fastDelegate.h:428)
    #4 0x4376ee	odfaeg::FastDelegate<void>::operator()<int>(int&&) const(this=0x7fffffffe300) (/usr/local/include/odfaeg/Core/fastDelegate.h:512)
    #5 0x437236	main(argv=1, argc=0x7fffffffe418) (/home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp:705)

  13. #33
    Invité
    Invité(e)
    Par défaut
    Ha non, c'est bon ça marche, j'avais oublié ça ici : std::foward<ArgU>(arg...)

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    template<std::size_t... I, class... ArgU>
    	R call(std::index_sequence<I...>, ArgU&&... args) const
    	{ return func(std::get<I>(param).get(std::forward<ArgU>(args)...)...); }

    Mais il reste un problème que j'ai oublié de te préciser, en fait setParam est appelée dans un thread et l'opérateur d'appel est appelé dans un autre thread, je ne peux donc pas passer les paramètres au moment de l'appel, je suis donc obligé de le faire lors de l'appel à setParam, c'est pour ça que je n'ai pas repris ton code auparavant. (Même si il marche!)

    Le mien fait appel à setParam avant l'appel.
    Dernière modification par Invité ; 12/10/2014 à 09h36.

  14. #34
    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
    C'est pas grave d'oublier d'avoir préciser, au moins là on avance.

    Déjà on va arrétêr de modifier setParam (nommé set dans mon code), lui il fait son boulot, il change tout les paramètres. On veut ajouter une fonctionnalité, on ajoute une fonction.

    Je te propose bind, et l'idée est de passer du code (le dernier que je te propose) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    odfaeg::delegate<void> func(foo,odfaeg::ph<0,int>());
    func(1);
    à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    odfaeg::delegate<void> func(foo,odfaeg::ph<0,int>());
    func.bind(1);
    func();
    PS: Je te dirais bien d'utiliser directement std::bind mais je sens venir la réponse : "Je peux pas car je dois pas changer d'objet".

    Si tu mènes le raisonnement tel que je l'ai mené pour l'opérateur d'appel, tu vas arriver à un fonctionnement similaire pour la fonction bind à rajouter partout. Au détail près qu'il faut convertir les paramètres vers des ref_val dans la première fonction de la pile (avant de prendre l'adresse et de passer en void*). Il faut aussi ajouter une fonction bind dans la hiérarchie ref_val. C'est un peu moins trivial que pour l'opérateur d'appel, mais le principe est le même.

  15. #35
    Invité
    Invité(e)
    Par défaut
    Et voila qui est fait!

    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
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
     
    #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>
    #define FUN_PARAM void* p0 =nullptr, void* p1 =nullptr, void* p2 =nullptr, void* p3 =nullptr
    #define FWD_PARAM p0,p1,p2,p3
    /**
      *\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& bind(FUN_PARAM) = 0;
    	virtual T& get(FUN_PARAM) = 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 <typename T>
    class RefVal;
    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& bind(FUN_PARAM) {
          return ref.get();
    	}
    	T& get(FUN_PARAM)
    	{ 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& bind(FUN_PARAM) {
          return val;
    	}
    	T& get(FUN_PARAM)
    	{ 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.*/
    };
    template<size_t I, class T>
    struct ph : IRefVal<T>
    {
    	std::unique_ptr<IRefVal<T>> clone() const
    	{ return std::make_unique<ph>(*this); }
        T& bind(FUN_PARAM) {
          return *static_cast<T*>
    			(std::get<I>(std::make_tuple(FWD_PARAM)));
    	}
    	T& get(FUN_PARAM)
    	{
    		return *static_cast<T*>
    			(std::get<I>(std::make_tuple(FWD_PARAM)));
    	}
    };
    /**
    *  \file  fastDelegate.h
    *  \class Ref
    *  \brief Warp a pointer.
    *  \author Duroisin.L
    *  \version 1.0
    *  \date 1/02/2014
    */
    /**
    *  \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 RefVal& rhs)
            *   \brief copy constructor, copy the wrapper with the right wrapper type.
            *   \param const RefVal& rhs : the wrapper to copy.
            */
    	template<size_t I>
    	RefVal(ph<I,T>&&)
    		: rv(std::make_unique<ph<I,T>>())
    	{}
    	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& bind(FUN_PARAM) {
    	    return rv->bind(FWD_PARAM);
    	}
    	T& get() const
    	{ return rv->get(); }
        template<class... Arg>
    	T& get(Arg&&... arg) const
    	{ return rv->get(std::forward<Arg>(arg)...); }
    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; };
    template<size_t I, class T>
    struct ToStoreImpl<ph<I,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);
    	}
    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 void bind(FUN_PARAM) = 0;
        virtual R operator()(FUN_PARAM) = 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.
        */
        void bind(FUN_PARAM) {
          bindParams(FWD_PARAM);
        }
    	R operator()(FUN_PARAM)
    	{ return call(std::make_index_sequence<sizeof...(ArgT)>(), FWD_PARAM); }
    	/** \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 = 0, typename... Arg>
        typename std::enable_if<I == sizeof...(ArgT)>::type
        bindParams(Arg&&... arg) {
     
        }
        template <std::size_t I = 0, typename... Arg>
        typename std::enable_if<(I < sizeof...(ArgT))>::type
        bindParams(Arg&&... arg) {
            std::get<I>(param) = std::get<I>(param).bind(std::forward<Arg>(arg)...);
            bindParams<I+1>(std::forward<Arg>(arg)...);
        }
        template<std::size_t... I, class... ArgU>
    	R call(std::index_sequence<I...>, ArgU&&... args) const
    	{ return func(std::get<I>(param).get(std::forward<ArgU>(args)...)...); }
    	DynamicFunction<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.
            */
    	template <typename... Arg>
    	void bind(Arg&&... arg) const {
    	     delegate->bind(&arg...);
    	}
    	template<class... Arg>
    	R operator()(Arg&&... arg) const
    	{ return (*delegate)(&arg...); }
    	/**\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 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!", 5);
    	}
    private:
    	std::unique_ptr<Delegate<R>> delegate; /**> holds the pointer to the generic delegate.*/
    };
    }
    #endif

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void f (int i, int j, int l) {
        std::cout<<"i : "<<i<<" j : "<<j<<" l : "<<l<<std::endl;
    }
    void f2 (int i) {
        std::cout<<"i : "<<i<<std::endl;
    }
    int main (int argv, char* argc[]) {
        odfaeg::FastDelegate<void> fd(&f, 1, 2, odfaeg::ph<0, int>());
        fd.bind(3);
        fd();
        return 0;
    }

    Sincèrement, le truc avec la fonction operator()(void*=nullptr, void*=nullptr, void*=nullptr, void*nullptr,...) je n'y avait vraiment pas pensé, surtout en donnant des arguments par défaut pour avoir toutes les surcharges possibles. (En fonction du nombre de placeholders)

    Je pense que j'aurai bien galéré si tu ne m'avais pas présenté l'idée!

    Pondre du code du genre celui de la STL ou bien de boost demande d'avoir, un tout autre niveau que je n'ai pas.

    Il n'y a plus qu'à modifier pour passer correctement les références avec des std::ref.

  16. #36
    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
    Rectification, pondre du code du niveau de boost ou la STL demande d'avoir un très bon niveau, d'être plusieurs, et de travailler longtemps.

    Vraiment longtemps. Et vraiment plusieurs.

    Et puis aussi, connaitre toutes les subtilités de la norme.

    Sinon, on fait comme tout le monde, on utilise boost, et on copie une STL open-source (toute, par construction?)
    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

  17. #37
    Invité
    Invité(e)
    Par défaut
    Ok oui mieux vaut l'utiliser le plus possible car tout seul je suis incapable de pondre du code comme celui de la STL. (Soit ça résulte à des crashs ou bien alors parce que je ne connais pas assez bien le langage)

    Déjà juste le draft, fait plus de 1000 pages.

    Bref cette librairie ne semble pas si petite qu'elle en a l'air.

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

Discussions similaires

  1. Changer le type de la classe /erreur de compilation
    Par xamarin dans le forum Général Java
    Réponses: 11
    Dernier message: 04/05/2014, 23h01
  2. comment changer le type d'une relation ?
    Par mitapi dans le forum Access
    Réponses: 5
    Dernier message: 21/05/2007, 10h29
  3. [Débutant] Changer le type d'une colonne
    Par david71 dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 08/11/2005, 11h26
  4. Probleme Alter - Changer le type d'un champ
    Par Yphon dans le forum Bases de données
    Réponses: 3
    Dernier message: 09/09/2005, 13h58
  5. Changer el type d'une variable sql sous postgre8/admin
    Par smag dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 24/08/2005, 12h31

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