title: Wrapping Containers to Maintain Consistency
body: <p>I'm wondering if it's a good idea to wrap C++ STL containers to maintain consistency and being able to swap the implementation without modifying client code.</p>
  
  <p>For example, in a project we use CamelCase for naming classes and member functions (<code>Foo::DoSomething()</code>), I would wrap <code>std::list</code> into a class like this:</p>
  
  <pre><code>template&lt;typename T&gt;
  class List
  {
      public:
          typedef std::list&lt;T&gt;::iterator Iterator;
          typedef std::list&lt;T&gt;::const_iterator ConstIterator;
          // more typedefs for other types.
  
          List() {}
          List(const List&amp; rhs) : _list(rhs._list) {}
          List&amp; operator=(const List&amp; rhs)
          {
              _list = rhs._list;
          }
  
          T&amp; Front()
          {
              return _list.front();
          }
  
          const T&amp; Front() const
          {
              return _list.front();
          }
  
          void PushFront(const T&amp; x)
          {
              _list.push_front(x);
          }
  
          void PopFront()
          {
              _list.pop_front();
          }
  
          // replace all other member function of std::list.
  
      private:
          std::list&lt;T&gt; _list;
  };
  </code></pre>
  
  <p>Then I would be able to write something like this:</p>
  
  <pre><code>typedef uint32_t U32;
  List&lt;U32&gt; l;
  l.PushBack(5);
  l.PushBack(4);
  l.PopBack();
  l.PushBack(7);
  
  for (List&lt;U32&gt;::Iterator it = l.Begin(); it != l.End(); ++it) {
      std::cout &lt;&lt; *it &lt;&lt; std::endl;
  }
  // ...
  </code></pre>
  
  <p>I believe most of the modern C++ compliers can optimize away the extra indirection easily, and I think this method has some advantages like:</p>
  
  <p>I can extend the functionality of the List class easily. For instance, I want a shorthand function that sorts the list and then call <code>unique()</code>, I can extend it by adding a member function:</p>
  
  <pre><code> template&lt;typename T&gt;
   void List&lt;T&gt;::SortUnique()
   {
       _list.sort();
       _list.unique();
   }
  </code></pre>
  
  <p>Also, I can swap the underlying implementation (if needed) without any change on the code they uses <code>List&lt;T&gt;</code> as long as the behavior is the same. There are also other benefits because it maintains consistency of naming conventions in a project, so it doesn't have <code>push_back()</code> for STL and <code>PushBack()</code> for other classes all over the project like:</p>
  
  <pre><code>std::list&lt;MyObject&gt; objects;
  // insert some MyObject's.
  while ( !objects.empty() ) {
      objects.front().DoSomething();
      objects.pop_front();
      // Notice the inconsistency of naming conventions above.
  }
  // ...
  </code></pre>
  
  <p>I'm wondering if this approach has any major (or minor) disadvantages, or if this is actually a practical method.</p>
  
  <p>Okay, thanks for the answers so far. I think I may have put too much on naming consistency in the question. Actually naming conventions are not my concern here, since one can provide an exactly same interface as well:</p>
  
  <pre><code>template&lt;typename T&gt;
  void List&lt;T&gt;::pop_back()
  {
      _list.pop_back();
  }
  </code></pre>
  
  <p>Or one can even make the interface of another implementation look more like the STL one that most C++ programmers are already familiar with. But anyway, in my opinion that's more of a style thing and not that important at all.</p>
  
  <p>What I was concerned is the consistency to be able to change the implementation details easily. A stack can be implemented in various ways: an array and a top index, a linked list or even a hybrid of both, and they all have the LIFO characteristic of a data structure. A self-balancing binary search tree can be implemented with an AVL tree or a red-black tree also, and they both have <code>O(logn)</code> average time complexity for searching, inserting and deleting.</p>
  
  <p>So if I have an AVL tree library and another red-black tree library with different interfaces, and I use an AVL tree to store some objects. Later, I figured (using profilers or whatever) that using a red-black tree would give a boost in performance, I would have to go to every part of the files that use AVL trees, and change the class, method names and probably argument orders to its red-black tree counterparts. There are probably even some scenarios that the new class do not have an equivalent functionality written yet. I think it may also introduce subtle bugs also because of the differences in implementation, or that I make a mistake.</p>
  
  <p>So what I started to wonder that if it is worth the overhead to maintain such a wrapper class to hide the implementation details and provide an uniform interface for different implementations:</p>
  
  <pre><code>template&lt;typename T&gt;
  class AVLTree
  {
      // ...
      Iterator Find(const T&amp; val)
      {
          // Suppose the find function takes the value to be searched and an iterator
          // where the search begins. It returns end() if val cannot be found.
          return _avltree.find(val, _avltree.begin());
      }
  };
  
  template&lt;typename T&gt;
  class RBTree
  {
      // ...
      Iterator Find(const T&amp; val)
      {
          // Suppose the red-black tree implementation does not support a find function,
          // so you have to iterate through all elements.
          // It would be a poor tree anyway in my opinion, it's just an example.
          auto it = _rbtree.begin(); // The iterator will iterate over the tree
                                     // in an ordered manner.
          while (it != _rbtree.end() &amp;&amp; *it &lt; val) {
              ++it;
          }
          if (*++it == val) {
              return it;
          } else {
              return _rbtree.end();
          }
      }
  };
  </code></pre>
  
  <p>Now, I just have to make sure that <code>AVLTree::Find()</code> and <code>RBTree::Find()</code> does exactly the same thing (i.e. take the value to be searched, return an iterator to the element or <code>End()</code>, otherwise). And then, if I want to change from an AVL tree to a red-black tree, all I have to do is change the declaration:</p>
  
  <pre><code>AVLTree&lt;MyObject&gt; objectTree;
  AVLTree&lt;MyObject&gt;::Iterator it;
  </code></pre>
  
  <p>to:</p>
  
  <pre><code>RBTree&lt;MyObject&gt; objectTree;
  RBTree&lt;MyObject&gt;::Iterator it;
  </code></pre>
  
  <p>and everything else will be the same, by maintaining two classes.</p>