title: Is there any real risk to deriving from the C++ STL containers?
body: <p>The claim that it is a mistake ever to use a standard C++ container as a base class surprises me. </p>
  
  <p>If it is no abuse of the language to declare ...</p>
  
  <pre><code>// Example A
  typedef std::vector&lt;double&gt; Rates;
  typedef std::vector&lt;double&gt; Charges;
  </code></pre>
  
  <p>... then what, exactly, is the hazard in declaring ...</p>
  
  <pre><code>// Example B
  class Rates : public std::vector&lt;double&gt; { 
      // ...
  } ;
  class Charges: public std::vector&lt;double&gt; { 
      // ...
  } ;
  </code></pre>
  
  <p>The positive advantages to B include:</p>
  
  <ul>
  <li>Enables overloading of functions because f(Rates &amp;) and f(Charges &amp;) are distinct signatures</li>
  <li>Enables other templates to be specialized, because X&lt;Rates&gt; and X&lt;Charges&gt; are distinct types</li>
  <li>Forward declaration is trivial</li>
  <li>Debugger probably tells you whether the object is a Rates or a Charges</li>
  <li>If, as time goes by, Rates and Charges develop personalities &mdash; a Singleton for Rates, an output format for Charges &mdash; there is an obvious scope for that functionality to be implemented.  </li>
  </ul>
  
  <p>The positive advantages to A include:</p>
  
  <ul>
  <li>Don't have to provide trivial implementations of constructors etc</li>
  <li>The fifteen-year-old pre-standard compiler that's the only thing that will compile your legacy doesn't choke</li>
  <li>Since specializations are impossible, template X&lt;Rates&gt; and template X&lt;Charges&gt; will use the same code, so no pointless bloat.</li>
  </ul>
  
  <p>Both approaches are superior to using a raw container, because if the implementation changes from vector&lt;double&gt; to vector&lt;float&gt;, there's only one place to change with B and <em>maybe</em> only one place to change with A (it could be more, because someone may have put identical typedef statements in multiple places).</p>
  
  <p>My aim is that this be a specific, answerable question, not a discussion of better or worse practice.  Show the worst thing that can happen as a consequence of deriving from a standard container, that would have been prevented by using a typedef instead.</p>
  
  <p>Edit:</p>
  
  <p>Without question, adding a destructor to class Rates or class Charges would be a risk, because std::vector does not declare its destructor as virtual.  There is no destructor in the example, and no need for one.  Destroying a Rates or Charges object will invoke the base class destructor.  There is no need for polymorphism here, either.  The challenge is to show something bad happening as a consequence of using derivation instead of a typedef.</p>
  
  <p>Edit: </p>
  
  <p>Consider this use case:</p>
  
  <pre><code>#include &lt;vector&gt;
  #include &lt;iostream&gt;
  
  void kill_it(std::vector&lt;double&gt; *victim) { 
      // user code, knows nothing of Rates or Charges
  
      // invokes non-virtual ~std::vector&lt;double&gt;(), then frees the 
      // memory allocated at address victim
      delete victim ; 
  
  }
  
  typedef std::vector&lt;double&gt; Rates;
  class Charges: public std::vector&lt;double&gt; { };
  
  int main(int, char **) {
    std::vector&lt;double&gt; *p1, *p2;
    p1 = new Rates;
    p2 = new Charges;
    // ???  
    kill_it(p2);
    kill_it(p1);
    return 0;
  }
  </code></pre>
  
  <p>Is there any possible error that even an arbitrarily hapless user could introduce in the ??? section which will result in a problem with Charges (the derived class), but not with Rates (the typedef)?  </p>
  
  <p>In the Microsoft implementation, vector&lt;T&gt; is itself implemented via inheritance.  vector&lt;T,A&gt; is a publicly derived from _Vector_Val&lt;T,A&gt;  Should containment be preferred? </p>