I have a derived class interface for which my base class needs to define the following three protected member arrays:
template<size_t n> class Base{
public:
static constexpr size_t n_ = n;
};
class BaseCat: protected Base<4>{
private:
// define arrays conveniently here, using brace notation
double A0[] = {0,1,2,3,4,5,6,7,8,9}; // this is the desired part
double A1[] = {13,-2};
// ...
protected:
// the following three lines are the boilerplate
double* A[] = {A0,A1,A2,A3}; // this is the undesired part
double* x[] = {x0,x1,x2,x3};
double* b[] = {b0,b1,b2,b3};
};
// the implementation of "Derived" requires A[],x[],b[] of length n to exist.
using DerivedCat = Derived<CatBase,CatBase::n_>;
This could be code written for each of the classes BaseDog:Base<3>, BaseCat:Base<4>, BaseMouse:Base<24>, and each time I hard-code some polyhedra in A,x,b for the respective model. A derived class ProcessedBase<BaseCat,BaseCat::n_> will need the protected members A,x,b to exist of according size n.
As far as I understand, macros cannot be used because of n
, which is not necessarily always of value 4.
Template functions also cannot be used because A0,A1,... are hand-written variable names, hence they would have to be hand-written in the templated assignment function in turn, and would have to be passed to it, which is as much boilerplate as writing them into brace-enclosed lists.
Finally, one could try to force a mapping of names A0 to A[i] in a base of Base, but then the convenient definition of A0 via brace-enclosed list in the upper part is impossible.
Can I get the best of both worlds, i.e. keep the desired part while avoiding the undesired part as commented in the code?
Would this work for you?
template <size_t n> class Base
{
public:
static constexpr size_t n_ = n;
};
class BaseCat: protected Base <4>
{
protected:
double A [n_] [10] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 13, -2 },
{ 14, -3 },
{ 15, -4 }
};
// x, b, ...
};
Which is pretty much what @463035818_is_not_an_ai said.
Note that this reserves more storage for A
than is actually needed, but maybe that's not an issue for you. And it's definitely time to think about making A
const
(or static constexpr
).