Is it possible to get the type of the derived class from base class without using template in C++?

Suppose I have some unrelated classes, that I want all of them to have a pointer of themselves. Naturally I could use template to achieve this:

template <typename T>
struct Base {
  // omitted the code to setup the variable
  static T *ptr;
}

class Derived1 : Base<Derived1> {}
class Derived2 : Base<Derived2> {}

// To use:

Derived1 d();
d.ptr->func();

My question is, can we achieve this without template, especially with the introduction of so many features in C++20 and 23 (such as Concepts)?

Ideally I’d love to have this:

struct Base {
  using Derived = std::directly_derived_type(Base);
  static Derived *ptr;
}

class Derived1 : Base {}
class Derived2 : Base {}

In this case if Base is ever instantiated without being a base class, compiler should refuse to compile the code because Derived can’t be resolved.

Answer

Based on the discussion, there is no template-less approach to CRTP. So I guess I’ll stick to the current code.