title: Bizarre error message in VC12 when attempting to create pool allocator
body: <p>I am attempting to create a simple pool allocator that can work with containers like list and map.  First, I have the class <code>free_list</code> which inherits from the node type that is used by the container and uses a specialized forward linked list (with all its memory already allocated--allocation occurs when the first item is allocated by the allocator) to give and take back memory requested in the allocator's <code>allocate</code> and <code>deallocate</code> functions.  Then I have the class <code>pool_alloc</code> which implements the allocator itself and returns and accepts in its allocation and deallocation functions <code>free_list&lt;T&gt;</code> object types.</p>
  
  <p>The problem child is this statement: <code>m_next-&gt;give_back(ptr);</code> under <code>pool_alloc::deallocate</code>, which returns VC12 error C2664: It says I cannot convert from type '<code>free_list&lt;T&gt;*</code>' to type '<code>free_list&lt;free_list&lt;T&gt;&gt;*</code>'.</p>
  
  <p>I do not understand why <code>free_list&lt;T&gt;::give_back</code> expects type <code>free_list&lt;free_list&lt;T&gt;&gt;*</code> when one would expect it to expect <code>free_list&lt;T&gt;*</code>.</p>
  
  <p>Is there any way to fix this? </p>
  
  <p>The full source code is below:</p>
  
  <pre><code>#include &lt;algorithm&gt;
  
  template&lt;class T&gt;
  class free_list : public T {
  public:
      free_list* init(std::size_t num_elements) {
  
          m_next = this;
          free_list* temp = m_next + 1;
  
          free_list* runner = m_next;
          for (std::size_t s = 1; s &lt; num_elements; ++s) {
              runner-&gt;m_next = temp;
              runner = temp;
              temp = runner + 1;
          }
          runner-&gt;m_next = nullptr;
  
          return m_next;
      }
  
      free_list* obtain() {
          free_list* head = m_next;
          m_next = m_next-&gt;m_next;
          return head;
      }
  
      void give_back(free_list* ptr) {
          ptr-&gt;m_next = m_next;
          m_next = ptr;
      }
  
      free_list* m_next;
  
  };
  
  template&lt;class T&gt;
  class pool_alloc {
      typedef pool_alloc&lt;T&gt; myt;
  
  public:
      typedef std::size_t size_type;
      typedef std::ptrdiff_t difference_type;
      typedef free_list&lt;T&gt; value_type;
      typedef T&amp; reference;
      typedef const T&amp; const_reference;
      typedef free_list&lt;T&gt;* pointer;
      typedef const free_list&lt;T&gt;* const_pointer;
  
      template&lt;class U&gt;
      struct rebind {
          typedef pool_alloc&lt;U&gt; other;
      };
  
      pool_alloc() : data(nullptr), m_next(nullptr), capacity(4096), allocated(0) {}
      pool_alloc(std::size_t capacity) : data(nullptr), m_next(nullptr), capacity(capacity), allocated(0) {}
  
      T* address(reference ref) {
          return &amp;ref;
      }
  
      const T* address(const_reference ref) const {
          return &amp;ref;
      }
  
      std::size_t max_size() const {
          return capacity;
      }
  
      pointer allocate(std::size_t) {
          if (allocated &gt;= capacity) throw(std::bad_alloc());
          if (allocated == 0) {
              data = (void*) new char[capacity * sizeof(free_list&lt;T&gt;)];
              m_next = static_cast&lt;free_list&lt;value_type&gt;*&gt;(data);
              m_next-&gt;init(capacity);
          }
          return m_next-&gt;obtain();
      }
  
      void deallocate(pointer ptr, std::size_t) {
          m_next-&gt;give_back(ptr);
          --allocated;
          if (allocated == 0) {
              delete[](char*)(data);
              data = nullptr;
              m_next = nullptr;
          }
      }
  
      template&lt;class T, class... Args&gt;
      void construct(T* ptr, Args&amp;&amp;... args) {
          ::new ((void*) ptr) T(std::forward&lt;Args&gt;(args)...);
      }
  
      template &lt;class T&gt;
      void destroy(T* ptr) {
          ptr-&gt;~T();
      }
  
      bool operator==(const myt&amp; other) {
          return (char)(data) == (char)(other.data);
      }
  
      bool operator!=(const myt&amp; other) {
          return !operator==(other);
      }
  
  private:
  
      void* data;
      free_list&lt;value_type&gt;* m_next;
      std::size_t capacity;
      std::size_t allocated;
  
  };
  </code></pre>