Consider the following contrived example of a templated array definition:
template <typename t, unsigned int n> class TBase
{
protected:
t m_Data[n];
//...
};
template <typename t, unsigned int n> class TDerived : public TBase<t, n>
{
TDerived()
{
}
};
I can specialize this type to provide a non-default constructor for an array of length 2 as follows:
template <typename t> class TDerived<t, 2> : public TBase<t, 2>
{
public:
TDerived(const t& x0, const t& x1)
{
m_Data[0] = x0;
m_Data[1] = x1;
}
};
int main()
{
TDerived<float, 2> Array2D_A(2.0f, 3.0f); //uses specialised constructor
TDerived<float, 3> Array3D_A; //uses default constructor
return 0;
}
Is there some other way I can create a class that has different constructor options constrained against template parameters at compile-time without the requirement for a complete class specialisation for each variation?
In other words, is there some way I can have specialised constructors in the TBase class without the need for the intermediary step of creating TDerived whilst preserving the functionality of TBase?
I think deriving your class from a base class is not relevant to the question here, that’s a mere implementation detail. What you really seem to be after is if there’s a way to partially specialize member functions, like the constructor. Do you want something like this?
This doesn’t work. You always have to specialize the entire class. The reason is simple: You have to know the full type of the class first before you even know which member functions exist. Consider the following simple situation:
Now
Bar<T>::somefunction()depends onT, but the function only exists whenTis notint, becauseBar<int>is an entirely different class.Or consider even another specialization
template <> class Bar<double> : public Zip {};— even the polymorphic nature of a class can be entirely different in a specialization!So the only way you can provide
specializationsnew declarations of members, including constructors, is by specializing the entire class. (You can specialize the definition of existing functions, see @Alf’s answer.)