You can, with a bit of trickery. This pattern is sometimes called “template subclassing” and is used extensively in the SeqAn library.
The trick is to give the base class an additional template argument tag which determines the type identity:
template <typename T, typename Spec = void>
struct A { … };
// inheritance tag:
struct Derived { };
template <typename T>
struct A<T, Derived> : public A<T, void> { … };
Here, void
denotes the base (you could also use a dedicated tag Base
but void
works fine) and Derived
, an empty struct, denotes the derived class.
Now you can instantiate and use the templates as follows:
A<int> the_base;
A<int, Derived> the_derived;
the_base.do_something();
the_derived.do_something();
For a real-world example, consider the String
class from SeqAn:
String<Dna> some_dna = "GATTACA";
String<Dna, Packed> more_dna = "GATTACA";
The second type derived from the first one, but is a specialisation which packs its characters as tightly as possible (for DNA, this means putting four DNA characters in each byte).