title: Inherit from STL container in C++11
body: <p>I have been thinking about inheriting from STL container in C++11. I know that this should not be done without some considerations since there is no virtual destructors.</p>
  
  <p>Using typedefs is, from what I have understood the preferred way to give names to STL containers.</p>
  
  <p>However typedefs are not without problems by themselves. First of all they can not easily be forward declared and two typedefs might accidently be the same type.</p>
  
  <p>Ponder the following:</p>
  
  <pre><code>typedef std::vector&lt;int&gt; vec_a_t;
  typedef std::vector&lt;float&gt; vec_b_t;
  
  void func(const vec_a_t&amp; v);
  void func(const vec_b_t&amp; v);
  </code></pre>
  
  <p>The two functions should behave differently depending on the logical type <code>vec_a_t</code> or <code>vec_b_t</code></p>
  
  <p>This situation will work fine until someone changes <code>vec_a_t</code> to </p>
  
  <pre><code>typedef std::vector&lt;float&gt; vec_a_t;
  </code></pre>
  
  <p>Now a call to <code>func()</code> is suddenly ambiguous. A realistic example for <code>func()</code> is</p>
  
  <pre><code>std::ostream&amp; operator&lt;&lt;(std::ostream&amp; ost, const vec_a_t&amp; v);
  </code></pre>
  
  <p>Now if we instead inherit like</p>
  
  <pre><code>class Vector : public std::vector&lt;int&gt;
  {};
  
  std::ostream&amp; operator&lt;&lt;(std::ostream&amp; ost, const Vector&amp; v);
  </code></pre>
  
  <p>It will be possible do also declare </p>
  
  <pre><code>class Vector2 : public std::vector&lt;int&gt; {};
  
  std::ostream&amp; operator&lt;&lt;(std::ostream&amp; ost, const Vector2&amp; v);
  </code></pre>
  
  <p>Which will clearly be disambigious.</p>
  
  <p>However since <code>std::vector</code> does not have virtual destructors deriving from them like this is wrong and can cause problems.</p>
  
  <p>Instead we try</p>
  
  <pre><code>class Vector : private std::vector&lt;int&gt;
  {
  public:
     using::size;
     //Add more using declarations as needed.
  };
  </code></pre>
  
  <p>Before C++11 there was issues with this also, since we would have to redeclare the constructors and it would have been possible to subclass our Vector class.</p>
  
  <p>However in C++11 it is possible to do the following</p>
  
  <pre><code>class Vector final : private std::vector&lt;int&gt;
  {
  public:
     using std::vector&lt;value_type&gt;::vector;
     using std::vector&lt;value_type&gt;::size;
     //More using directives as needed.
  };
  </code></pre>
  
  <p>From what I can see this solves a lot of the problems of why one should not derive from STL containers. It also has the following benefits:</p>
  
  <ol>
  <li>It is a distinct type, that can not cause ambiguous calls if its underlying type is changed.</li>
  <li>It can be forward declared.</li>
  <li>There is no need to re-implement forwarding methods to an internal member type.</li>
  <li>It will behave as a true STL container (if the relevant/all methods are exposed with <code>using</code>).</li>
  <li>Its methods can be overridden, e.g. to track calls to <code>push_back</code></li>
  </ol>
  
  <p>My questions, based on the previous discussion, are:</p>
  
  <ul>
  <li><p>Do you see anything wrong with deriving STL containers like this in
  C++11?</p></li>
  <li><p>Am I missing something or can this style of coding cause any problems
  down the line?</p></li>
  <li><p>Would it cause any problems if this new type had a state of its own
  (e.g. track the number of calls to <code>push_back</code>)?</p></li>
  </ul>
  
  <p>EDIT:</p>
  
  <p>I know the standard answer is "Use a private field". I was wondering what the realistic downsides of the proposed solution in C++11 is? The downside of a private field is to have to re-implement a whole range of methods that just forwards to the underlying type.</p>
  
  <p>This approach would not be an option either.</p>
  
  <pre><code>class Vector
  {
  private:
     std::vector&lt;int&gt; m_type
  public:
     std::vector&lt;int&gt;&amp; get_type(){return m_type;}
  };
  </code></pre>
  
  <p>EDIT:</p>
  
  <p>Do not use the <code>typedef coll_t</code> in the final solution to avoid answers that my new typedef causes problems, it was just there to ease the typing.</p>