title: Expected a type, got a template
body: <p>I'm writing a sort of "asynchronous factory" where time-consuming constructions of concrete objects are deferred to <code>std::async</code> tasks.
  Each <code>AsyncFactory</code> will store a <em>smart</em> pointer to the object.</p>
  
  <p>[This is not the most correct application of <em>Factory Pattern</em>, but it is for the sake of a MWE].</p>
  
  <pre><code>#include &lt;future&gt;
  #include &lt;memory&gt;
  #include &lt;type_traits&gt;
  #include &lt;cassert&gt;
  
  /**
   * @param I is the interface type
   * @param Ptr is the memory handler. Default = unique; optional = shared
   */
  template &lt;class I, template&lt;class&gt; class Ptr = std::unique_ptr&gt;
  class AsyncFactory
  {
      /**
       * @param C - the concrete type for the interface I
       * @param Ts - the variadic params
       */
      template &lt;class C, typename... Ts&gt;
      void _future_reload(Ts&amp;&amp;... params)
      {
          if (std::is_same&lt;Ptr, std::unique_ptr&gt;())                       // line21
          {
              ptr = std::make_unique&lt;C&gt;(std::forward&lt;Ts&gt;(params)...);
          }
          else
          {
              if (std::is_same&lt;Ptr, std::shared_ptr&gt;())                   // line27
              {
                  ptr = std::make_shared&lt;C&gt;(std::forward&lt;Ts&gt;(params)...);
              }
              else
              {
                  static_assert(0, "unacceptable type for smart pointer");// line33
              }
          }
      }
  
  public: 
  
      Ptr&lt;I&gt; ptr;
  
      AsyncFactory() :
          ptr(nullptr)
      {}
  
      /**
       * @param C - the concrete type. Default: the interface type
       * @param Ts - the variadic params
       */
      template &lt;class C = I, typename... Ts&gt;
      void reload(Ts&amp;&amp;... params)
      {
          std::future&lt;void&gt; fReload =
                          std::async(std::launch::async,
                          &amp;AsyncFactory::_future_reload&lt;C, Ts...&gt;, this,
                          std::forward&lt;Ts&gt;(params)...);
      }
  };
  
  
  class BaseVirtual
  {
      virtual void foo() = 0;
  };
  
  class DerivedConcrete :
      public BaseVirtual
  {
      void foo() override {;}
  };
  
  
  int main()
  {
      AsyncFactory&lt;BaseVirtual, std::shared_ptr&gt; fac;
  
      fac.reload&lt;DerivedConcrete&gt;();
  }
  </code></pre>
  
  <p>Problems arise with the smart pointer. I have to call different <code>make</code>rs for <code>unique</code>/<code>shared</code> pointers. But <code>g++ -std=c++14</code> stops with</p>
  
  <pre><code>f.cpp: In member function ‘void AsyncFactory&lt;I, Ptr&gt;::_future_reload(Ts&amp;&amp; ...)’:
  f.cpp:21:44: error: type/value mismatch at argument 1 in template parameter list for ‘template&lt;class, class&gt; struct std::is_same’
     if (std::is_same&lt;Ptr, std::unique_ptr&gt;())
                                          ^
  f.cpp:21:44: note:   expected a type, got ‘Ptr’
  f.cpp:21:44: error: type/value mismatch at argument 2 in template parameter list for ‘template&lt;class, class&gt; struct std::is_same’
  f.cpp:21:44: note:   expected a type, got ‘unique_ptr’
  f.cpp:27:45: error: type/value mismatch at argument 1 in template parameter list for ‘template&lt;class, class&gt; struct std::is_same’
      if (std::is_same&lt;Ptr, std::shared_ptr&gt;())
                                           ^
  f.cpp:27:45: note:   expected a type, got ‘Ptr’
  f.cpp:27:45: error: type/value mismatch at argument 2 in template parameter list for ‘template&lt;class, class&gt; struct std::is_same’
  f.cpp:27:45: note:   expected a type, got ‘shared_ptr’
  f.cpp:33:9: error: static assertion failed: unacceptable type for smart pointer
       static_assert(0, "unacceptable type for smart pointer");
  </code></pre>