This is a little hard to describe in words, I'll start with a snippet and try to explain what is attempted as best I can.
struct NonTrivialBase {
virtual void TakeAction();
virtual ~NonTrivialBase();
};
template< typename P >
struct NonTrivial_D1 : NonTrivialBase
{
P case1;
virtual void TakeAction() {
// do something with case1
}
NonTrivial_D1( P arg ) : case1(arg) {
}
};
template< typename Q >
struct NonTrivial_D2 : NonTrivialBase
{
Q case2;
virtual void TakeAction() {
// do something with case2
}
NonTrivial_D2( Q arg, int arg2 ) : case2(arg,arg2) {
}
};
class Unit
{
NonTrivialBase * Member;
public:
template< typename P2 >
Unit (P2 par) : Member ( new NonTrivial_D1<P2>(par) ) {}
template< typename Q2 >
Unit (Q2 par, int par2) : Member ( new NonTrivial_D2<Q2>(par,par2) ) {}
};
template< unsigned short Count >
class Collection
{
Unit units[ Count ];
public:
template< typename P3 >
Collection( P3 par )
// : units { [ 0 ... Count - 1 ] = {par} }
// ^^ problem
{}
template< typename Q3 >
Collection( Q3 par, int arg )
// : units { [ 0 ... Count - 1 ] = {par, arg} }
// ^^ problem
{}
};
If it isn't clear (may not be) I'm trying to come up with a container class that can initialize an array of non-trivially-constructed objects, all of which will have the same parameters to whichever constructor is deemed valid. The essence of the design is Collection
and Unit
have the same constructors in order to manage a compile-time-known number of identically-constructed "units" only through Collection
references.
For various reasons it is not possible to initialize Unit
without a constructor. Both Collection
and Unit
classes are intended to act as base classes themselves.
I expect something like this to work but again, std::array
is not available in my environment (GCC 4.8.1-4 / MinGW) and I want to avoid if possible including other libraries just for this one thing. Boost isn't an option for me, for example.
Then, the array-initializer syntax itself.
I understand this is GCC-only but that isn't a problem. I can't even get the syntax to behave correctly when the array-element type requires template parameters for the constructor (automatically determined or not, I can live with either). I get an error to the equivalent of:
error: expected identifier before numeric constant
: units { [ 0 ... Count - 1 ] = {par} }
^
I believe that the array-range initializer in and of itself should be supported, courtesy of this reference.
And lastly I just need to be clear that this solution is not scalable because of Count
Unit units[Count] = { {param}, {param}, ... }
such as suggested here.
In the grand scheme of things I don't have to do it this way but now that I have had the idea, I'm genuinely curious how to approach this...
Relevant GCC parameters (just in case) - g++ -std=gnu++0x -O3 -Wall -Wconversion -c -fmessage-length=0
EDIT
To clarify some requirements -
Heap vs Stack - preference is for stack but I can live with heap-based solutions. Bear in mind Unit may not be copyable.
std::array
- I cannot use this. The suggested duplicate relies on this being available.