title: How to ensure runtime type covariance in C++?
body: <p>Say I have an interface class and templated subclass</p>
  
  <pre><code>struct IPort {
      virtual bool can_connect_to(std::shared_ptr&lt;IPort&gt; p) = 0;
      std::shared_ptr&lt;IPort&gt; receiver;
  };
  
  template &lt;class T&gt;
  struct Port : IPort {
      bool can_connect_to(std::shared_ptr&lt;IPort&gt; p) override {
          // what goes here?
      }
  
      void send(T* t) {
          auto p = std::static_pointer_cast&lt;Port&gt;(receiver);
          p-&gt;on_recv(t);
      }
  
      std::function&lt;void(T*)&gt; on_recv;
  };
  </code></pre>
  
  <p>The template parameter can be any type. I have some base types (<code>Base</code> and <code>Other</code> below) as well as a derived type (<code>Derived</code>).</p>
  
  <pre><code>struct Base {
      virtual const char* get_data() = 0;
      virtual size_t get_size() = 0;
  };
  
  struct Derived : public Base {
      std::string str;
      const char* get_data() override { return str.c_str(); }
      size_t get_size() override { return str.size(); }
  };
  
  struct Other {
      double x, y, z;
  };
  </code></pre>
  
  <p>Ideally I should be able to send a derived type from a port to another port that accepts the base type (e.g. <code>Port&lt;Derived&gt;</code> should be able to connect to <code>Port&lt;Base&gt;</code>). On the other hand, I should not be able to send incompatible types (<code>Port&lt;Other&gt;</code> should not be able to connect to <code>Port&lt;Base&gt;</code>).</p>
  
  <pre><code>auto sender1 = std::make_shared&lt;Port&lt;Derived&gt;&gt;();
  auto sender2 = std::make_shared&lt;Port&lt;Other&gt;&gt;();
  auto receiver = std::make_shared&lt;Port&lt;Base&gt;&gt;([](Base* t) {
      // do something with t
  });
  
  sender1-&gt;can_connect_to(receiver); // should return true
  sender2-&gt;can_connect_to(receiver); // should return false
  </code></pre>
  
  <p>What can I put in <code>can_connect_to</code> to verify that the port passed in has a templated type that is a superclass of the template of the sending port?</p>
  
  <p>Also, why does the <code>static_pointer_cast</code> in <code>send</code> work? It seems to do the correct thing, but I don't understand how it's even valid c++ since there's no template parameter to <code>Port</code>.</p>