11

According to cppreference, std::basic_ostringstream can be instantiated with a custom allocator. Since C++11, allocators are allowed to have state and my custom allocator class does have internal per-instance state (actually each allocator instance has a pointer to an instance of a MemPool class, to which it forwards all allocation requests). This is why my allocator type can't just simply be default-constructed and be expected to work because after all, where is it going to get the address of the MemPool instance it's supposed to use from?

Unfortunately, if you take a look at the constructor prototypes of std::basic_ostringstream, you can see that none of the supported constructors actually take an allocator instance! I'm pretty sure that std::basic_ostringstream will have to make some allocation(s) to construct its resulting string, and I really want it to use my allocator for those, but how is it going to do that if I have no way of telling it which specific MemPool instance to use??

Have I overlooked something here? I feel like I must have but I sure don't see how at the moment.

2
  • 3
    Sounds like LWG 2210 missed a few Commented May 30, 2014 at 16:37
  • @Cubbi: Since it seems that this is indeed just an oversight in the C++ standards specification, why don't you post your comment as an actual answer so I can mark it as the accepted answer? Commented May 31, 2014 at 13:55

2 Answers 2

3

It is possible that the resolution to the LWG defect #2210, which added allocator instances to the constructors of many standard library containers, was not sufficiently thorough and the streams were overlooked. Or perhaps it wasn't clear enough how to approach them. I would suggest filing a new library defect report (or perhaps asking first in std-discussion)

Sign up to request clarification or add additional context in comments.

3 Comments

I've filed a defect report as you suggested -> cplusplus.github.io/LWG/lwg-active.html#2429
LWG DR 2210 is clearly about allocator-aware containers (it says so in the title!) so was never meant to cover basic_stringstream which is defined in a completely different clause
Looks like this will be fixed in c++20l that is, there is a std::basic_ostringstream constructor that can take an allocator object.
3

You can pass a basic_string<C, T, A> object to the constructor, and I expect all implementations will copy the allocator from that string object (probably via a call to allocator_traits<A>::select_on_container_copy_construction()) but that isn't clearly specified by the standard, and probably should be.

2 Comments

Hmm, I hadn't thought of that at all. That's actually a very nice workaround (if it really works ... I haven't tried it out yet)!
Here is a shim until c++20, based on this answer: template<class C, class T=std::char_traits<C>, class A=std::allocator<C>> struct basic_ostringstream_from_allocator_object : public std::basic_ostringstream<C,T,A> { basic_ostringstream_from_allocator_object(const A &a) : std::basic_ostringstream<C,T,A>( std::basic_string<C,T,A>(a)) {} };

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.