Your design looks like CRTP since Child_Type1
inherits fro a base class parameterized by Child_Type1
itself but without fully adopting the principles of this pattern, ie. one should only pass the derived class to the base class and not other stuff (like T
and Child_Type1<T>::Inner
in your example).
If you fully follow the CRTP, you should be able to write:
template <class T>
class Child_Type1 : public Base<Child_Type1<T>> {};
and then try to recover in Base
the types you need, ie. T
and Child_Type1<T>::Inner
Note that you can recover T
from Child_Type1<T>
with a little helper (see also this:
template <typename T>
struct get_T;
template <template <typename> class X,typename T>
struct get_T<X<T>> { using type = T; };
Following the answer of @Jarod42 and using this trick, you could have something like:
////////////////////////////////////////////////////////////////////////////////
// see https://stackoverflow.com/questions/78048504/how-to-write-a-template-specialization-of-a-type-trait-that-works-on-a-class-tem
template <typename T>
struct get_T;
template <template <typename> class X,typename T>
struct get_T<X<T>> { using type = T; };
////////////////////////////////////////////////////////////////////////////////
template <typename T>
struct Inner;
////////////////////////////////////////////////////////////////////////////////
template <class DERIVED>
class Base
{
public:
using T = typename get_T<DERIVED>::type;
using inner = Inner<DERIVED>;
virtual void test(void) = 0;
};
////////////////////////////////////////////////////////////////////////////////
template <class T>
class Child_Type1 : public Base<Child_Type1<T>>
{
public:
Base<Child_Type1<T>>::inner * var;
void test(void) override { }
};
template <typename T> struct Inner<Child_Type1<T>> { T some_variable; };
////////////////////////////////////////////////////////////////////////////////
int main()
{
Child_Type1<int> c1 = Child_Type1<int>();
}