为什么我需要std :: get_temporary_buffer?

Kir*_*sky 84 c++ buffer memory-management stl temporary

我应该用什么目的std::get_temporary_buffer?标准说明如下:

获得一个指向存储的指针,足以存储多达n个相邻的T对象.

我认为缓冲区将在堆栈上分配,但事实并非如此.根据C++标准,这个缓冲区实际上不是暂时的.这个函数对全局函数有什么优势::operator new,它不构造对象.我是对的,以下陈述是等同的吗?

int* x;
x = std::get_temporary_buffer<int>( 10 ).first;
x = static_cast<int*>( ::operator new( 10*sizeof(int) ) );
Run Code Online (Sandbox Code Playgroud)

这个函数只存在于语法糖吗?为什么有temporary它的名字?


1996年7月1日Dr. Dobb's Journal提出了一个用例来实现算法:

如果没有缓冲区可以分配,或者它小于请求的缓冲区,算法仍能正常工作,它只会减慢速度.

Geo*_*che 43

Stroustrup在"The C++ Programming Language"(§19.4.4,SE)中说:

这个想法是系统可以保留许多固定大小的缓冲区以便快速分配,这样n个对象的请求空间可以产生超过n的空间.然而,它也可能产生更少的收益,因此一种使用方式get_temporary_buffer()是乐观地要求很多,然后使用可能的东西.
[...]因为它get_temporary_buffer()是低级的并且可能针对管理临时缓冲区进行优化,所以它不应该用作newallocator :: allocate()的替代方法来获取长期存储.

他还开始介绍这两个函数:

算法通常需要临时空间来执行可接受的操作.

......但似乎没有在任何地方提供临时长期的定义.

一个故事中的"从数学到泛型编程"提到,斯捷潘诺夫在原来的STL的设计但前提是伪造的占位符的实现,:

令他惊讶的是,多年后他发现提供STL实施的所有主要供应商仍在使用这种可怕的实施[...]

  • 看起来VC++的实现只是一个循环,调用`operator new`并连续使用较小的参数,直到分配成功为止.那里没有特别的优化. (11认同)
  • 与g ++ 4.5相同 - 看起来很好,但供应商忽略了. (9认同)
  • 听起来他们应该将这个功能包装在一个名为`crazy_allocator`的类中 (4认同)

Jer*_*emy 17

微软的标准库人说下面(这里):

  • 你能解释一下何时使用'get_temporary_buffer'吗?

它有一个非常专业的目的.请注意,它不会抛出异常,例如new(nothrow),但它也不会构造对象,这与new(nothrow)不同.

它在STL内部用于stable_partition()等算法.当有像N3126这样的魔术词时会发生这种情况25.3.13 [alg.partitions]/11:stable_partition()具有复杂性"最多(最后 - 第一个)*log(最后 - 第一个)交换,但只有交换的线性数量足够的额外记忆." 当出现"如果有足够的额外内存"的魔术词时,STL使用get_temporary_buffer()来尝试获取工作空间.如果可以,那么它可以更有效地实现算法.如果它不能,因为系统危险地运行接近内存不足(或涉及的范围很大),算法可以回退到较慢的技术.

99.9%的STL用户永远不需要了解get_temporary_buffer().


jal*_*alf 9

该标准表示它为最多 n元素分配存储空间.换句话说,您的示例可能会返回一个足以容纳5个对象的缓冲区.

虽然这似乎很难想象一个好的用例.也许如果你正在一个内存受限的平台上工作,那么获得"尽可能多的内存"是一种方便的方法.

但是在这样一个受限制的平台上,我想你会尽可能地绕过内存分配器,并使用一个内存池或你可以完全控制的东西.


Rae*_*ald 6

我应该出于什么目的使用 std::get_temporary_buffer?

该函数在 C++17 中已弃用,因此现在的正确答案是“无用,请勿使用”。