title: Type erasure: Retrieving value - type check at compile time
body: <p>I have a limited set of very different types, from which I want to store instances in a single collection, specifically a map. To this end, I use the type erasure idiom, ie. I have a non-templated base class from which the templated, type specific class inherits:</p>
  
  <pre><code>struct concept
  {
     virtual std::unique_ptr&lt;concept&gt; copy() = 0; // example member function
  };
  
  template &lt;typename T&gt;
  struct model : concept
  {
     T value;
     std::unique_ptr&lt;concept&gt; copy() override { ... }
  }
  </code></pre>
  
  <p>I then store unique_ptrs to concept in my map. To retrieve the value, I have a templated function which does a dynamic cast to the specified type. </p>
  
  <pre><code>template &lt;typename T&gt;
  void get(concept&amp; c, T&amp; out) {
     auto model = dynamic_cast&lt;model&lt;T&gt;&gt;(&amp;c);
     if (model == nullptr) throw "error, wrong type";
     out = model-&gt;value;
  }
  </code></pre>
  
  <p>What I don't like about this solution is, that specifying a wrong T is only detected at runtime. I'd really really like this to be done at compile time. </p>
  
  <p>My options are as I see the following, but I don't think they can help here:</p>
  
  <ul>
  <li><p>Using ad hoc polymorphism by specifying free functions with each type as an overload, or a template function, but I do not know where to store the result.</p>
  
  <ul>
  <li><p>Using CRTP won't work, because then the base class would need to be templated.</p></li>
  <li><p>Conceptually I would need a virtual function which takes an instance of a class where the result will  be stored. However since my types are fundamentally different, this class would need to be templated, which does not work with virtual.</p></li>
  </ul></li>
  </ul>
  
  <p>Anyways, I'm not even sure if this is logically possible, but I would be very glad if there was a way to do this.</p>