This doesn't compile: #include <memory> #include <sstream> #include <cassert> template<typename T> struct Alloc : std::allocator<T> { template<typename U> struct rebind { using other = Alloc<U>; }; Alloc(int id) : id(id) { } template<typename U> Alloc(const Alloc<U>& a) : id(a.id) { } int id; }; using string = std::basic_string<char, std::char_traits<char>, Alloc<char>>; using stringbuf = std::basic_stringbuf<char, std::char_traits<char>, Alloc<char>>; int main() { string s(Alloc<char>(1)); stringbuf b(s); assert( b.str().get_allocator() == s.get_allocator() ); } The basic_stringbuf constructor default-initializes its basic_string member, which default-initializes its allocator.
I'm planning to change libstdc++ so that basic_stringbuf(const basic_string&, ios_base::mode) calls get_allocator() on the string parameter for its internal string member. I don't plan to allow changing the allocator after construction. That seems to be the easiest behaviour to explain, and also to implement.
> That seems to be the easiest behaviour to explain, and also to implement. Yep. Simple and makes sense. Fixed in revision 309838. It would be nice to *say* that in the standard, too ;-) Do you want to file an LWG issue?