title: Why do std::shared_ptr<void> work
body: <p>I found some code using std::shared_ptr to perform arbitrary cleanup at shutdown. At first I thought this code could not possibly work, but then I tried the following:</p>
  
  <pre><code>#include &lt;memory&gt;
  #include &lt;iostream&gt;
  #include &lt;vector&gt;
  
  class test {
  public:
    test() {
      std::cout &lt;&lt; "Test created" &lt;&lt; std::endl;
    }
    ~test() {
      std::cout &lt;&lt; "Test destroyed" &lt;&lt; std::endl;
    }
  };
  
  int main() {
    std::cout &lt;&lt; "At begin of main.\ncreating std::vector&lt;std::shared_ptr&lt;void&gt;&gt;" 
              &lt;&lt; std::endl;
    std::vector&lt;std::shared_ptr&lt;void&gt;&gt; v;
    {
      std::cout &lt;&lt; "Creating test" &lt;&lt; std::endl;
      v.push_back( std::shared_ptr&lt;test&gt;( new test() ) );
      std::cout &lt;&lt; "Leaving scope" &lt;&lt; std::endl;
    }
    std::cout &lt;&lt; "Leaving main" &lt;&lt; std::endl;
    return 0;
  }
  </code></pre>
  
  <p>This program gives the output:</p>
  
  <pre><code>At begin of main.
  creating std::vector&lt;std::shared_ptr&lt;void&gt;&gt;
  Creating test
  Test created
  Leaving scope
  Leaving main
  Test destroyed
  </code></pre>
  
  <p>I have some ideas on why this might work, that have to do with the internals of std::shared_ptrs as implemented for G++. Since these objects wrap the internal pointer together with the counter the cast from <code>std::shared_ptr&lt;test&gt;</code> to <code>std::shared_ptr&lt;void&gt;</code> is probably not hindering the call of the destructor. Is this assumption correct?</p>
  
  <p>And of course the much more important question: Is this guaranteed to work by the standard, or might further changes to the internals of std::shared_ptr, other implementations actually break this code?</p>