Why do I need std::get_temporary_buffer?

Solution 1:

Stroustrup says in "The C++ Programming Language" (§19.4.4, SE):

The idea is that a system may keep a number of fixed-sized buffers ready for fast allocation so that requesting space for n objects may yield space for more than n. It may also yield less, however, so one way of using get_temporary_buffer() is to optimistically ask for a lot and then use what happens to be available.
[...] Because get_temporary_buffer() is low-level and likely to be optimized for managing temporary buffers, it should not be used as an alternative to new or allocator::allocate() for obtaining longer-term storage.

He also starts the introduction to the two functions with:

Algorithms often require temporary space to perform acceptably.

... but doesn't seem to provide a definition of temporary or longer-term anywhere.

An anecdote in "From Mathematics to Generic Programming" mentions that Stepanov provided a bogus placeholder implementation in the original STL design, however:

To his surprise, he discovered years later that all the major vendors that provide STL implementations are still using this terrible implementation [...]

Solution 2:

Microsoft's standard library guy says the following (here):

  • Could you perhaps explain when to use 'get_temporary_buffer'

It has a very specialized purpose. Note that it doesn't throw exceptions, like new (nothrow), but it also doesn't construct objects, unlike new (nothrow).

It's used internally by the STL in algorithms like stable_partition(). This happens when there are magic words like N3126 25.3.13 [alg.partitions]/11: stable_partition() has complexity "At most (last - first) * log(last - first) swaps, but only linear number of swaps if there is enough extra memory." When the magic words "if there is enough extra memory" appear, the STL uses get_temporary_buffer() to attempt to acquire working space. If it can, then it can implement the algorithm more efficiently. If it can't, because the system is running dangerously close to out-of-memory (or the ranges involved are huge), the algorithm can fall back to a slower technique.

99.9% of STL users will never need to know about get_temporary_buffer().

Solution 3:

The standard says it allocates storage for up to n elements. In other words, your example might return a buffer big enough for 5 objects only.

It does seem pretty difficult to imagine a good use case for this though. Perhaps if you're working on a very memory-constrained platform, it's a convenient way to get "as much memory as possible".

But on such a constrained platform, I'd imagine you'd bypass the memory allocator as much as possible, and use a memory pool or something you have full control over.

Solution 4:

For what purpose I should use std::get_temporary_buffer?

The function is deprecated in C++17, so the correct answer is now "for no purpose, do not use it".

Solution 5:

ptrdiff_t            request = 12
pair<int*,ptrdiff_t> p       = get_temporary_buffer<int>(request);
int*                 base    = p.first;
ptrdiff_t            respond = p.sencond;
assert( is_valid( base, base + respond ) );

respond may be less than request.

size_t require = 12;
int*   base    = static_cast<int*>( ::operator new( require*sizeof(int) ) );
assert( is_valid( base, base + require ) );

the actual size of base must greater or equal to require.