Reputation: 748
I have a class that I've templatized to get compile-time polymorphism as a alternative to run-time polymorphism through inheritance.
I have two different specializations of some of the methods in this class. Let's call them T_a
and T_b
.
I want to initialize a const, yet non-static array of objects of this class with different values based on the template parameter.
template<class T>
class A {
const anotherObject& aO;
const ConfigPar configPars[];
}
First, I thought I could just specialize the member:
template<class T>
class A {
const ConfigPar configPars[];
A(T t);
}
template<>
const ConfigPar A<T_a>::configPars[] {
{anotherObject.foo1, "bar1"},
{anotherObject.foo2, "bar2"},
}
template<>
const ConfigPar A<T_b>::configPars[] {
{anotherObject.foo1, "bar1"},
{anotherObject.foo2, "bar2"},
{anotherObject.foo3, "bar3"},
}
However, this doesn't work, since apparently you can only specialize static class members. However, the values of the objects in the configPars
array depend on another instance member, so I can't make configPars
static.
Next, I thought about overloading A
's constructor, and just initializing configPars
differently in the constructors:
template<class T>
class A {
const ConfigPar configPars[];
A(T_a t) : configPars{
{anotherObject.foo1, "bar1"},
{anotherObject.foo2, "bar2"},
} {}
A(T_b t) : configPars{
{anotherObject.foo1, "bar1"},
{anotherObject.foo2, "bar2"},
{anotherObject.foo3, "bar3"},
} {}
}
However, in this my compiler complains that error: too many initializers for 'const ConfigPar [0]'
. Apparently I can't leave the size of the array out in its declaration?
The problem is that the array sizes differ between the two specializations (or overloaded constructors, in this case).
How do I handle this?
Upvotes: 1
Views: 93
Reputation: 180594
The size of all class members must be known inside the class definition. This includes the size of the array member. What you can do is determine what size array you have based on what T
is and supply that in the definition. That could look like
template<class T>
class A {
const ConfigPar configPars[(std::is_same_v<T, T_a> ? 2 : 3)]; // 2 for T_a, 3 otherwise
A(T t);
};
// specialization of constructor for T_a
template<>
A<T_a>::A(T_a t) : configPars{
{1, "bar1"},
{2, "bar2"},
}
{
// constructor body, use t here
}
// specialization of constructor for T_b
template<>
A<T_b>::A(T_b t) : configPars{
{1, "bar1"},
{2, "bar2"},
{3, "bar3"},
}
{
// constructor body, use t here
}
Upvotes: 3