title: Return templated type from container of heterogeneous templated values
body: <p>I am placing instances of a templated class containing heterogeneous template values into a container, such as a std::vector. When accessing a particular element from said vector, I require that the precise templated type is returned, not just the base pointer <code>WrapperBase*</code> . I've dabbled with boost::any, boost::variant, and the base class / templated child class as shown below. A compile time solution would be ideal (perhaps some meta templating magic); otherwise, a runtime RTTI-based solution would suffice.</p>
  
  <p>In a perfect world, I could do something like this:</p>
  
  <pre><code>vector&lt; WrapperBase &gt; v;
  v.push_back( Wrapper&lt;int&gt;{1} );
  v.push_back( Wrapper&lt;float&gt;{3.14f} );
  auto v = vector[0].get(); //typeid( decltype( v) ).name() would be "int"
  auto v = vector[1].get(); //typeid( decltype( v) ).name() would be "float"
  </code></pre>
  
  <p>Boost variant almost provided a solution; however, I can only access the specific type within the <code>operator()()</code> method and cannot return it. The type will be consumed by further functions, so I am not able to have the visitor method perform the desired work.</p>
  
  <p>This code is available <a href="http://coliru.stacked-crooked.com/a/5a44681322cdbd77" rel="nofollow noreferrer">http://coliru.stacked-crooked.com/a/5a44681322cdbd77</a></p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;type_traits&gt;
  #include &lt;vector&gt;
  #include &lt;boost/variant.hpp&gt;
  #include &lt;boost/any.hpp&gt;
  
  struct WrapperBase
  {
     template&lt; typename T &gt;
     T* get();
  };
  
  template&lt; typename T &gt;
  struct Wrapper : WrapperBase
  {
     Wrapper( T* t ) : WrapperBase(), _val( t ) {}
     T* get() { return _val; }
     T* _val;
  };
  
  template&lt; typename T &gt;
  T* WrapperBase::get()
  {
     return static_cast&lt;Wrapper&lt;T&gt;&gt;( this )-&gt;get();
  }
  
  struct Visitor : boost::static_visitor&lt;int&gt; //sadly, we can only return ints :(.
  {
     int operator()( Wrapper&lt;int&gt;&amp; b ) const
     {
        auto bType = *b.get();
        std::cout &lt;&lt; "b type is " &lt;&lt; typeid( decltype( bType ) ).name() &lt;&lt; "... Val is " &lt;&lt; bType &lt;&lt; "...\n";
        return 2;
     }
  
     int operator()( Wrapper&lt;float&gt;&amp; b ) const
     {
        auto bType = *b.get();
        std::cout &lt;&lt; "b type is " &lt;&lt; typeid( decltype( bType ) ).name() &lt;&lt; "... Val is " &lt;&lt; bType &lt;&lt; "...\n";
        return 6;
     }
  
     int operator()( Wrapper&lt;std::string&gt;&amp; b ) const
     {
        auto bType = *b.get();
        std::cout &lt;&lt; "b type is " &lt;&lt; typeid( decltype( bType ) ).name() &lt;&lt; "... Val is " &lt;&lt; bType &lt;&lt; "...\n";
        return 12345;
     }
  
  };
  
  int main( int argc, char* args[] )
  {
     std::cout &lt;&lt; "Hello World...\n";
  
     int ia = 5;
     Wrapper&lt;int&gt; a{ &amp;ia };
  
     float fb = 3.1415f;
     Wrapper&lt;float&gt; b{ &amp;fb };
  
     std::string s = "testing this...\n";
     Wrapper&lt;std::string&gt; c{ &amp;s };
  
     auto aType = *a.get(); //aType is "int"
     std::cout &lt;&lt; "a type is " &lt;&lt; typeid( decltype( aType ) ).name() &lt;&lt; "... Val is " &lt;&lt; aType &lt;&lt; "...\n";
  
     auto bType = *b.get(); //aType is "float"
     std::cout &lt;&lt; "b type is " &lt;&lt; typeid( decltype( bType ) ).name() &lt;&lt; "... Val is " &lt;&lt; bType &lt;&lt; "...\n";
  
     auto cType = *c.get(); //aType is "std::string"
     std::cout &lt;&lt; "c type is " &lt;&lt; typeid( decltype( cType ) ).name() &lt;&lt; "... Val is " &lt;&lt; cType &lt;&lt; "...\n";
  
     std::vector&lt; boost::any &gt; vec;
  
     vec.push_back( &amp;a );
     vec.push_back( &amp;b );
     vec.push_back( &amp;c );
  
     //for( int i = 0; i &lt; vec.size() ; i++ )
     //{
     //In my actual code, I have no way of knowing I need to cast to &lt;int&gt; and therefore cannot cast.
     //   auto t = boost::any_cast&lt;Wrapper&lt;int&gt;*&gt;( vec[i] );
     //   std::cout &lt;&lt; "[" &lt;&lt; i &lt;&lt; "] type is " &lt;&lt; typeid( decltype( t ) ).name() &lt;&lt; "... Val is " &lt;&lt; t &lt;&lt; "...\n";    
     //}    
     std::cout &lt;&lt; "...\n...\n...\n";
  
     using VAR = boost::variant&lt; Wrapper&lt;int&gt;, Wrapper&lt;float&gt;, Wrapper&lt;std::string&gt; &gt;;
  
     std::vector&lt; VAR &gt; myVar;
     myVar.push_back( a );
     myVar.push_back( b );
     myVar.push_back( c );
     for (int i = 0; i &lt; myVar.size() ; i++)
     {
        auto v = myVar[i];
        //apply_visitor is VERY close to what I want - I have precise type, but only within operator()()
        std::cout &lt;&lt; boost::apply_visitor( Visitor(), v ) &lt;&lt; "\n";
     }
  
     std::cout &lt;&lt; "...\n...\n...\n";
  
     std::vector&lt; WrapperBase &gt; v;
     v.push_back( a );
     v.push_back( b );
     v.push_back( c );
  
     //for (int i = 0; i &lt; v.size() ; i++)
     //{
     //   auto t = v[i].get&lt;int&gt;(); //same problem as boost::any, but instead I have pointer to base class
     //   std::cout &lt;&lt; "["&lt;&lt;i&lt;&lt;"] type is " &lt;&lt; typeid( decltype( t )).name() &lt;&lt; "... Val is " &lt;&lt; t &lt;&lt; "...\n";
     //   
     //}
  
  
     return 0;
  }
  </code></pre>