Ho un numero elevato di classi che vengono utilizzate per decorare alcuni metodi specifici.Riduzione del boilerplate durante i metodi di decorazione
Esiste un modo pulito per ridurre la quantità di codice boilerplate (principalmente tutti i parametri del costruttore e dei membri per mantenerli) che deve essere aggiunto a ciascuna di queste classi? O, ancora meglio, c'è un modo migliore per farlo?
Non riesco a utilizzare metodi virtuali e posso solo utilizzare il sottoinsieme di funzioni C++ 11 supportate da gcc 4.6 e vs2010.
Credo che i costruttori ereditari di C++ 11 possano essere d'aiuto, ma nessuno dei compilatori li supporta e non sono a conoscenza di una soluzione alternativa.
Ecco un esempio di ciò che queste classi attualmente assomigliano:
template<class Underlying, class T1>
struct A : Base<A<Underlying, T1> >
{
typedef AImpl<decltype(declval<Underlying>().foo()), T1> impl;
A(Underlying u, T1 t1) :
u_(u),
t1_(t1)
{}
impl foo() const { return impl(u_.foo(), t1_); }
impl bar() const { return impl(u_.bar(), t1_); }
const Underlying u_;
T1 t1_;
};
template<class Underlying, class T1, class T2>
struct B : Base<B<Underlying, T1, T2> >
{
typedef BImpl<decltype(declval<Underlying>().bar()), T1, T2> impl;
B(Underlying u, T1 t1, T2 t2) :
u_(u),
t1_(t1),
t2_(t2)
{}
impl foo() const { return impl(u_.bar(), 999, t2_); }
impl bar() const { return impl(u_.foo(), t1_, t2_); }
const Underlying u_;
T1 t1_;
T2 t2;
};
Ma non in VC++ 2010 ... – ildjarn
Penso che l'uso di 'forward' potrebbe essere leggermente errato (inefficiente almeno) qui. Per impostazione predefinita, qualsiasi uso di 'forward' dovrebbe essere in una chiamata di metodo con tipi di parametri dedotti. Ciò significa 'modello B (sotto u, V && ... t): u_ (u), t_ (std :: forward (t) ...) {}'. Tre cose: 1) La funzione stessa dovrebbe essere un modello. 2) Gli argomenti dovrebbero essere presi come 'U && ...', e 'forward' deve essere usato. Il codice corrente * copierà * i parametri in 'B' e quindi potrebbe * spostarli * nella classe base. Idealmente, vuoi zero copie e invece muovi completamente, quando possibile. –
Due cose, get non è un membro di tuple nell'implementazione standard (è in Boost) e l'uso di forward non è corretto nel costruttore. Dovrebbe essere 'template B (Sotto u, V && ... v): u_ (u), t_ (std :: forward (v) ...) {}'. –
DRayX