title: C++ - "unspecialized class template" in unordered_map with shared_ptr to template class
body: <p>I have a class <code>UISceneParams</code> and I use it to store some parameters that I want to send over to a UIScene. It contains a <code>unordered_map</code> of <code>shared_ptr</code>s to <code>DataParam</code> instances.
  The problem is that my DataParam must use a template and feature multiple data types.</p>
  <p>Is there any way I can make the <code>unordered_map</code> use multiple data types of DataParams?</p>
  <p>I currently call this like this:</p>
  <pre><code>UISceneParams p;
  p.AddParam&lt;int&gt;(&quot;test_value&quot;, 123);
  p.AddParam&lt;int&gt;(&quot;test_value2&quot;, 456);
  </code></pre>
  <p>and in my scene I get the parameters using the <code>GetParam&lt;T&gt;</code> method, like this:</p>
  <pre><code>int value1 = p.GetParam&lt;int&gt;(&quot;test_value&quot;, 0);
  int value2 = p.GetParam&lt;int&gt;(&quot;test_value2&quot;, 0);
  </code></pre>
  <p>I've been trying many ways to circumvent the errors, but I am a beginner with templates in C++. Can someone get me on the right track?</p>
  <p>UISceneParams.h</p>
  <pre><code>#pragma once
  #include &lt;string&gt;
  #include &lt;unordered_map&gt;
  #include &lt;memory&gt;
  
  using namespace std;
  
  template &lt;typename T&gt;
  class DataParam {
  public:
      DataParam(string t, T v) {
          _tag = t;
          _val = v;
      }
  
      T Value() const {
          return _val;
      }
  
      string Tag() const {
          return _tag;
      }
  private:
      string _tag;
      T _val;
  };
  
  class UISceneParams {
  public:
      bool HasParam(string tag) {
          return params.find(tag) != params.end();
      }
  
      template &lt;typename T&gt;
      void AddParam(string tag, T value) {
          if (HasParam(tag)) params.erase(tag);
          params.insert({ tag, make_shared&lt;DataParam&gt;(tag, value) });
      }
  
      template &lt;typename T&gt;
      T GetParam(string tag, T def_value) {
          if (!HasParam(tag)) return def_value;
          auto p = params.find(tag)-&gt;second;
          return p-&gt;Value;
      }
  private:
      unordered_map&lt;string, shared_ptr&lt;DataParam&gt;&gt; params;
  };
  </code></pre>
  <p>Edit: Final code</p>
  <pre><code>#pragma once
  #include &lt;string&gt;
  #include &lt;unordered_map&gt;
  #include &lt;memory&gt;
  
  using namespace std;
  
  class IDataParam
  {
  public:
      virtual ~IDataParam() = default;
  };
  
  template &lt;typename T&gt;
  class DataParam : public IDataParam {
  public:
      DataParam(string t, T v) {
          _tag = t;
          _val = v;
      }
  
      T Value() const {
          return _val;
      }
  
      string Tag() const {
          return _tag;
      }
  private:
      string _tag;
      T _val;
  };
  
  class UISceneParams {
  public:
      bool HasParam(string tag) {
          return params.find(tag.data()) != params.end();
      }
  
      template &lt;typename T&gt;
      void AddParam(string tag, T value) {
          if (HasParam(tag)) params.erase(tag);
          params.insert({ tag, make_shared&lt;DataParam&lt;T&gt;&gt;(tag, value) });
      }
  
      template &lt;typename T&gt;
      T GetParam(string tag, T def_value) {
          if (!HasParam(tag)) return def_value;
          auto p = dynamic_cast&lt;const DataParam&lt;T&gt; &amp;&gt;(*params.find(tag)-&gt;second);
          return p.Value();
      }
  private:
      unordered_map&lt;string, shared_ptr&lt;IDataParam&gt;&gt; params;
  };
  </code></pre>