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?
template <typename T, int N> class Foo
{
Foo(); // general
template <typename U> Foo<U, 2>(); // specialized, NOT REAL CODE
};
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:
template <typename T> class Bar
{
void somefunction(const T&);
};
template <> class Bar<int>
{
double baz(char, int);
};
Now Bar<T>::somefunction()
depends on T
, but the function only exists when T
is not int
, because Bar<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 specializations new declarations of members, including constructors, is by specializing the entire class. (You can specialize the definition of existing functions, see @Alf's answer.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With