First garbage collector
From a design and interface point of view, I find the use of:

auto a = heap.allocate("A");
cout &lt;&lt; a-&gt;value &lt;&lt; endl;


unnatural. I would expect a to act like a pointer to std::string since it's the value returned from a function named allocate using an object of type Heap&lt;std::string&gt;.

It would be more natural if:


*a evaluated to std::string&amp; (std::string const&amp; if a were const)
a-&gt; evaluated to std::string* (std::string const* if a were const)


Then, you could replace a-&gt;value by *a.

auto a = heap.allocate("A");
cout &lt;&lt; *a &lt;&lt; endl;


P.S. I haven't spent enough time delving into the implementation of Heap to suggest how it can be done.