Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reducing boilerplate when decorating methods

Tags:

c++

c++11

I have a large number of classes which are used to decorate a few specific methods.

Is there a clean way to reduce the amount of boilerplate code (mainly all the constructor parameters and members to hold them) that needs to be added to each of these classes? Or, even better, is there a nicer way to do this?

I can't use virtual methods, and can only use the subset of c++11 features supported by gcc 4.6 and vs2010.

I believe c++11 inheriting constructors would help here, but neither compiler supports them and I'm not aware of a workaround.

Here's an example of what these classes currently look like:

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;
};
like image 621
James Avatar asked Nov 05 '22 10:11

James


1 Answers

You could use variadic templates in GCC 4.6.

template<class Underlying, class... T>
struct B : Base<B<Underlying, T...>>
{
    typedef BImpl<decltype(declval<Underlying>().bar()), T...> impl;

    template<typename V...>
    B(Underlying u, V... v) :
        u_(u),
        t_(std::forward<V>(v)...)
    {}

    impl foo() const { return impl(u_.bar(), 999, std::get<1>(t_)); } // Not sure what the 999 is?
    impl bar() const { return impl(u_.foo(), std::get<0>(t_), std::get<1>(t_)); }

    const Underlying u_;
    std::tuple<T...> t_;
};
like image 119
ronag Avatar answered Nov 09 '22 14:11

ronag