How to use static constexpr attributes in derived with minimum boilerplate?

36 Views Asked by At

Question

What is the minimum boilerplate code in Derived, so that Derived can access static constexpr attributes of Base?

The focus of the question is removal of boilerplate from Derived.

Minimum working example

#include <iostream>
#include <array>

// Base only exists to remove boilerplate from Derived in defining a plethora of static constexpr attributes
template<size_t n_, std::array<const size_t,n_> a_> // ... and many more template arguments for Base
class Base{
public:
    static constexpr size_t n = n_;
    static constexpr std::array<const size_t,n_> a = a_;
    // static constexpr std::array<const size_t,n_> b = static_sum_over_static_array<const size_t>(a);
    // ... and many more non-trivial static constexpr attributes are defined here

    // trading one line less in Derived for hundred lines more in Base is fine
    static constexpr size_t get_n(){ return n; }
};

class Derived: public Base<10,{3,5,6,7,2,0,1,4,2,9}>{
    
    // boilerplate
    using Base<10,{3,5,6,7,2,0,1,4,2,9}>::n; 
    using Base<10,{3,5,6,7,2,0,1,4,2,9}>::a; 
    // using Base<10,{3,5,6,7,2,0,1,4,2,9}>::b; 
    // these lines with the "using" create an incredible amount of boilerplate
    
    // compact user code
    int x[n]; // I need to access the parent attributes

    // undesirable (boilderplate + unreadable)
    int y[get_n()];
};

int main() {
    Derived b;
}

Since this is a minimum example by requirements of stack overflow, the fact remains unrepresented that the sheer length of text to specify one realization of Base is ~200 characters on average.

The reason for Base to exist is so that classes like Derived can be implemented that use the static constexpr attributes in Base to create Derived attributes, such as x in the example.

If I have to write 30 boilerplate lines then that is actually useless. Also, there seems to be no way to hide the boilerplate with a macro since that in turn would require yet again to write the realization template arguments of Base twice (once in the inheritance declaration of Derived and once in the Macro call), which I want to avoid at all cost.

Remarks

The need for a long list of static constant expressions makes it appear as though Derived is a super-class, which is bad practice. The appearance is false, as Derived is customer code where they instantiate ~5 objects with (maybe 10 out of the 30, but each time different ones) with Base's attributes as template arguments to define an individual user application from convenient building blocks.

0

There are 0 best solutions below