title: How can I fake dependent types in C++ for non-constant, and local data?
body: <p>Below is some code which almost works. What I want to do is create memory pools which autodelete their contents on destruction (it's okay if it only works for plain old data), and have a compile time guarentee that the pool must always survive longer than the pointers to it's contents do. In my attempt to accomplish this, I made the pointers have the pool which they point to a part of their type. My strategy seems as if it should work but C++ only allows constant, or global data as template parameters which stops me programming how I want. For example, in the code below the memory pool must be a global value. How can I fake dependent types in C++ for non-constant, and local data?</p>
  
  <p>Here's the code, and a simple example showing how to use it. I apologize for not dealing with alignment issues, but this is just a simple proof of concept anyways.</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;cstdlib&gt;
  
  
  class pool;
  
  template&lt;typename T, pool&amp; H&gt;
  class reference;
  
  
  class pool {
  private:
   pool(const pool&amp;);
   pool&amp; operator=(const pool&amp;);
  
   const pool* operator&amp;() const;
   pool* operator&amp;();
  
  
   size_t size; 
   void *storage;
  
   size_t tag;
  
  public:
   pool() : size(0), storage(0) { }
   ~pool() { free(storage); }
  
  template&lt;typename, pool&amp;&gt; friend class reference;
  template&lt;typename T, pool&amp; H&gt; friend reference&lt;T, H&gt; allocate();
  };
  
  
  template&lt;typename T, pool &amp;H&gt;
  class reference {
  private:
   reference();
  
   size_t index;
  
   reference(size_t _index) : index(_index) { }
  
  public:
   friend class pool;
  
   void set(const T&amp; rvalue) const {
    *((T*)&amp;((char*)H.storage)[index]) = rvalue;
   }
  
   T operator*() const {
    return *((T*)&amp;((char*)H.storage)[index]);
   }
  
   reference&lt;T, H&gt;&amp; operator++() {
    index += sizeof(T);
    return *this;
   }
  
  template&lt;typename U, pool&amp; I&gt; friend reference&lt;U, I&gt; allocate();
  };
  
  // TODO: Add in alignment stuff
  template&lt;typename T, pool&amp; H&gt;
  reference&lt;T, H&gt; allocate() {
   const size_t old_size = H.size;
  
   H.size += sizeof(T);
   H.storage = realloc(H.storage, H.size);
  
   return reference&lt;T, H&gt;(old_size);
  }
  
  
  template&lt;pool&amp; H&gt;
  reference&lt;char, H&gt; get_line() {
   const reference&lt;char, H&gt; start = allocate&lt;char, H&gt;();
   reference&lt;char, H&gt; end = start;
  
   char input;
  
   for (;;) {
    input = std::cin.get();
  
    if ('\n' == input) {
     break;
    }
  
    end.set(input);
    end = allocate&lt;char, H&gt;();
   }
  
   end.set('\0');
  
   return start; 
  }
  
  template&lt;pool &amp;H&gt;
  std::ostream&amp; operator &lt;&lt;(std::ostream&amp; out, reference&lt;char, H&gt; start) {
   for (; *start != '\0'; ++start)
    std::cout.put(*start);
  
   return out;
  }
  
  
  pool input_pool;
  
  int main(int argc, char **argv) {
  
   std::cout &lt;&lt; "What is your name?" &lt;&lt; std::endl;
  
   const reference&lt;char, input_pool&gt; input_string = get_line&lt;input_pool&gt;();
  
   std::cout &lt;&lt; "Hello " &lt;&lt; input_string &lt;&lt; "!" &lt;&lt; std::endl;
  
  
   return 0;
  }
  </code></pre>