
GCC is correct. There is a get out clause in the library standard. Look at section 20.1.5 "Allocator requirements" paragraph 4 [snip]
Ah, that clears up my first confusion! Though it does leave me wondering, then, how allocators solve that part of the problem they were intended for. If the intent was in part to abstract out platform differences, that abstraction seems undermined by this shortcut. But this probably isn't the place to discuss it.
What that implies to me, and seems to be supported by gcc's list implementation, is that the nodes in my tree mustn't have a default ctor that actually does anything, because the only way to properly initialize objects using an allocator is through copying. Is that correct
I think not. My interpretation is that allocators require that their value_type is Copy Constructable but place no restriction on other ways they may be constructed.
That said, STL containers have been carefully designed to avoid the need default construct an object which will be subsequently assigned to. They can keep memory in an uninitialised state until an element is needed and then use copy construction.
This kind of makes sense ... In implementing a container, I certainly shouldn't have any reason to default-construct instances of the container's value type, except in cases like std::list's default fill constructor (where the default exemplar element can be created on the stack, avoiding any allocation issues). I was more concerned about my own internal node structure, where I did run into the problem of how to construct nodes. I suppose I will follow the standard library's convention of not default-constructing my nodes, even if calling placement new() directly -- rather than construct() -- would have been safe. The other thing I think I'll do is bite the bullet and purchase a copy of the standard. Seems like there's a lot in there that I can't find through a simple Google search! Thanks very much for your help, dr