title: Error converting form boost::shared_ptr<T> to std::shared_ptr<T>
body: <p>I wrote a function template to "convert"/repack a <code>boost::shared_ptr&lt;T&gt;</code> to a <code>std::shared_ptr&lt;T&gt;</code> and vice versa by following <a href="https://stackoverflow.com/a/12605002/3385047">this proposal</a>. It's working fine unless I have a <code>boost::shared_pt&lt;T&gt;</code> and the type of <code>T</code> is an abstract class. </p>
  
  <p>What I figured out so far is, that the problem occurs when <code>boost/shared_ptr.hpp</code> and <code>boost/shared_array.hpp</code> are included together. If only <code>boost/shared_ptr.hpp</code> is included it's working when the type of <code>T</code> is an abstract class. </p>
  
  <p>I'm using clang 3.3 and boost 1.55.0 . It would be great if someone could tell my why it's not working and how to get it working.
  <br /><br />
  Thanks for your help</p>
  
  <p><br /><br />
  Here is a minimal example:</p>
  
  <pre><code>//main.cpp
  
  #include &lt;boost/shared_array.hpp&gt; //removing this include and it's working
  #include &lt;boost/shared_ptr.hpp&gt;
  #include &lt;memory&gt;
  
  template&lt;typename SharedPointer&gt; struct Holder {
  
      SharedPointer p;
  
      Holder(const SharedPointer &amp;p) : p(p) {}
      Holder(const Holder &amp;other) : p(other.p) {}
      Holder(Holder &amp;&amp;other) : p(std::move(other.p)) {}
  
      void operator () (...) const {}
  };
  
  
  template&lt;class T&gt;
  std::shared_ptr&lt;T&gt; to_std_ptr(const boost::shared_ptr&lt;T&gt; &amp;p)
  {
      typedef Holder&lt;std::shared_ptr&lt;T&gt;&gt; H;
  
      if(H *h = boost::get_deleter&lt;H, T&gt;(p))  // get_deleter seems to cause the problem
      {
          return h-&gt;p;
      }
      else
      {
          return std::shared_ptr&lt;T&gt;(p.get(), Holder&lt;boost::shared_ptr&lt;T&gt;&gt;(p));
      }
  }
  </code></pre>
  
  <p><br /><br />
  Here the code I used to test it:</p>
  
  <pre><code>//main.cpp
  
  template&lt;typename T&gt; class Base 
  {
  public:
      T value;   
      virtual void abstract() = 0;
      virtual ~Base() {}
  };
  
  template&lt;typename T&gt; class Derived : public Base&lt;T&gt;
  {
  public:    
      virtual void abstract() override {}
      virtual ~Derived() {}
  };
  
  
  int main(int argc, const char * argv[])
  {
      boost::shared_ptr&lt;Base&lt;int&gt;&gt; ptr{new Derived&lt;int&gt;()};
  
      // error here
      std::shared_ptr&lt;Base&lt;int&gt;&gt; a = to_std_ptr(ptr);
  
      // no error here
      std::shared_ptr&lt;Base&lt;int&gt;&gt; b = to_std_ptr(boost::static_pointer_cast&lt;Derived&lt;int&gt;&gt;(ptr));
  
      return 0;
  }
  </code></pre>
  
  <p><br /><br />
  Here's the error message(shortened):</p>
  
  <pre><code>boost/smart_ptr/shared_array.hpp:111:102: error: array of abstract class type 'Base&lt;int&gt;'
      shared_array( shared_array&lt;Y&gt; const &amp; r, typename boost::detail::sp_enable_if_convertible&lt; Y[], T[] &gt;::type = boost::detail::sp_empty() )
  
  main.cpp:64:40: note: in instantiation of template class 'boost::shared_array&lt;Base&lt;int&gt; &gt;' requested here 
      if(H *h = boost::get_deleter&lt;H, T&gt;(p))
  
  main.cpp:86:36: note: in instantiation of function template specialization 'to_std_ptr&lt;Base&lt;int&gt; &gt;'requested here
      std::shared_ptr&lt;Base&lt;int&gt;&gt; i = to_std_ptr(ptr);
  
  main.cpp:23:18: note: unimplemented pure virtual method 'abstract' in 'Base'
      virtual void abstract() = 0;
  </code></pre>
  
  <p>What I get from the error message is that the compiler tried to create an array of abstract classes what of course doesn't work. But why is he even trying to do so and what has <code>boost/sharred_array</code> to do with that. Is he maybe picking the wrong overload for <code>boost::get_deleter</code>?  </p>