On Sunday, December 18, 2011 02:46:01 Andrei Alexandrescu wrote: > If this is a new notion, it might take a while for all of its aspects to > sink in. I'm not saying that to be smug - reference counting vs. other > methods of collecting garbage is definitely a difficult topic on today's > architectures, and I can say at least it took me quite a while to build > some reasonable mental model of the related tradeoffs.
After thinking about this a bit, I don't think that custom allocators are really going to work with classes very well. Unless you allocate the entire class with the custom allocator (as opposed to just telling the container to use the custom allocator), the memory won't be cleaned up until the object is collected by the GC (even though it's using a custom allocator to allocate its internals), in which case, what does the custom allocator really buy us? So, the idea of just passing the allocator to the container doesn't seem to cut it for a class. The object itself needs to be allocated with the custom allocator. On top of that, if you're allocating the container with a custom allocator, doesn't that risk issues like what the to-be-deprecated scope modifier causes? You practically end up having to wrap the class in a struct anyway, in which case, what's the point of using a class? Just in general, it's much harder to control the memory if the container is a class rather than a struct. With a struct, you can do pretty much whatever you want with the memory. Its lifetime is strictly controlled, which gives much greater opportunites to optimize its memory usage. With a class, it's going to be difficult to completely divorce the container from the GC in a clean manner. With a struct, we could easily make the default not use the GC at all, which would make the default use of the containers much more efficient. You also wouldn't have to worry about creating the container itself with an allocator and all of the potential issues that that brings. I don't particularly like the idea of the cost of passing the container around as a struct (since it's few member variables will have to be memcopied and the ref-counting will have to be done), but that's not a huge cost (though it _is_ a pervasive one), and I'm begginning to think that it's a necessary one if we want containers to be able to properly and efficiently manage their own memory. Depending on the use case, the benefits from the containers being able to fully manage their own memory without the programmer having to do anything special could easily outweigh the additional cost of passing a struct around. And if ranges over such containers are passed around more frequently than the containers themselves (as I would expect), then the minor cost of passing the container around is even less of a big deal, since it would primarily be the ranges being passed around. So, I'm beginning to think that we're going to have to go the struct route. - Jonathan M Davis