title: Can the this pointer be polymorphic?
body: <p>I thought that typeid was supposed to reveal the most derived type of it's parameter. But when I use it in a constructor like the below, it seems unaware of what the real type of the pointer is.</p>
  <p>When I pass it off to another class, it also seems to not know what the type is.</p>
  <p>Is this because the this pointer doesn't know what the real type is? Is there a way around this to determine the real derived type of the this pointer?</p>
  <p>In this below code, is there a way for <code>Thing&lt;T&gt;</code> to determine the derived type of the pointer passed to it?</p>
  <pre><code>#include &lt;concepts&gt;
  #include &lt;typeinfo&gt;
  #include &lt;iostream&gt;
  
  class FooBase;
  
  class ThingBase
  {
  public:
      virtual int GetThing(const FooBase* const foo) const = 0;
  };
  
  template&lt;typename T&gt;
  requires std::derived_from&lt;T, FooBase&gt;
  class Thing : public ThingBase
  {
  public:
      virtual int GetThing(const FooBase* const foo) const override
      {
          if(typeid(T) == typeid(*foo))
              return 0;
          return 1;
      }
  };
  
  class FooBase
  {
  public:
      FooBase(const ThingBase* const thing)
      :
          i(thing-&gt;GetThing(this))
      {
          std::cout &lt;&lt; &quot;Foo base is: &quot; &lt;&lt; typeid(*this).name() &lt;&lt; std::endl;
      }
  
      virtual ~FooBase() {}
  
      virtual const int&amp; GetBaseValue() const final
      {
          return i;
      }
  
  protected:
      int i;
  };
  
  class Foo : public FooBase
  {
  public:
      Foo(const ThingBase* const thing)
      :
          FooBase(thing),
          j(thing-&gt;GetThing(this))
      {
          std::cout &lt;&lt; &quot;Foo is: &quot; &lt;&lt; typeid(*this).name() &lt;&lt; std::endl;
      }
  
      const int&amp; GetChildValue() const
      {
          return j;
      }
  
  protected:
      int j;
  };
  
  int main()
  {
      Thing&lt;Foo&gt; thing;
  
      Foo foo1(&amp;thing);
  
      std::cout &lt;&lt; foo1.GetBaseValue() &lt;&lt; std::endl;
      std::cout &lt;&lt; foo1.GetChildValue() &lt;&lt; std::endl;
      std::cout &lt;&lt; &quot;foo1 is: &quot; &lt;&lt; typeid(foo1).name() &lt;&lt; std::endl;
  
      FooBase* foo2 = new Foo(&amp;thing);
  
      std::cout &lt;&lt; foo2-&gt;GetBaseValue() &lt;&lt; std::endl;
      std::cout &lt;&lt; &quot;foo2 is: &quot; &lt;&lt; typeid(*foo2).name() &lt;&lt; std::endl;
  
      return 0;
  }
  </code></pre>