I had a question on your implementation of the homework assignment from part 2. When you used your container_traits classes was there a particular reason why you didn't just create an additional set of specialized classes to implement the specialized erase methods? Was it just for simplicity of demonstration or is there a technical reason? I would think eliminating the need for the ignored argument would ultimately be a better solution since you wouldn't have to hope for an optimization by the compiler.

 

Something like this:

namespace meow
{
  namespace detail
  {
    struct vectorlike_tag {};
    struct listlike_tag {};
    struct associative_tag {};

    template <typename C> struct container_traits;

    template<typename T,typename A> struct container_traits<std::vector<T,A>>
    {
      typedef vectorlike_tag category;
    };

    template<typename T,typename A> struct container_traits<std::deque<T,A>>
    {
      typedef vectorlike_tag category;
    };

    template<typename T,typename A> struct container_traits<std::list<T,A>>
    {
      typedef listlike_tag category;
    };

    template<typename T,typename C, typename A> struct container_traits<std::set<T,C,A>>
    {
      typedef associative_tag category;
    };

    template<typename C> struct erase_helper;

    template<> struct erase_helper<vectorlike_tag>
    {
      template<typename Container, typename X>
      static void erase( Container& c, const X& x )
      {
        c.erase( std::remove(c.begin(), c.end(), x), c.end() );
      }
    };

    template<> struct erase_helper<listlike_tag>
    {
      template<typename Container, typename X>
      static void erase( Container& c, const X& x )
      {
        c.remove(x);
      }
    };

    template<> struct erase_helper<associative_tag>
    {
      template<typename Container, typename X>
      static void erase( Container& c, const X& x )
      {
        c.erase(x);
      }
    };
  }

  template <typename Container, typename X> void erase( Container& c, const X& x )
  {
    detail::erase_helper< typename detail::container_traits<Container>::category >::erase(
      c, x );
  }
}