有没有办法从 STL 获取无开销的原始内存容器

Is there a way to get a overhead-free raw memory container from the STL

本文关键字:原始 内存 开销 STL 获取 有没有      更新时间:2023-10-16

std::vector<unsigned char>std::vector<char>是显而易见的候选者(取决于上下文(,事实上,大多数示例代码都使用它们:

https://stackoverflow.com/a/18816228/4442671

但是,由于std::vector必须构造所有对象,因此与简单的动态分配相比,您最终会执行无关memset():https://godbolt.org/g/TKkwmp

这没什么大不了的,但它仍然是无缘无故执行的额外 O(N( 工作,所以感觉就像打破了"如果你不需要它就不要付钱"的原则。

围绕new[]编写一个完整的 RAII 包装器并不难,但我不禁想知道:

有没有办法从 STL 中获取一个连续未初始化内存的动态容器,还是我被困在重新发明那个轮子上?

编辑:我对@Someprogrammerdude的reserve()建议获得如此多的选票感到非常困惑。有人可以解释一下取消引用 0 大小向量的保留内存不是一个糟糕的主意吗?

std::get_temporary_buffer正是这样做的:

分配未初始化的连续存储,该存储应足以存储最多计数 T 类型的相邻对象。该请求不具有约束力,实现分配的可能少于或超过存储相邻对象计数所需的数量。

您可以将其与std::unique_ptr配对以提供自定义析构函数,因为此类缓冲区需要使用std::return_temporary_buffer()释放。

可悲的是它在 C++17 中被弃用,并在 C++20 :(

中删除您可以使用输出迭代器在此临时缓冲区中构建对象:std::raw_storage_iterator

#include <iostream>
#include <string>
#include <memory>
#include <algorithm>
int main()
{
const std::string s[] = {"This", "is", "a", "test", "."};
std::string* p = std::get_temporary_buffer<std::string>(5).first;
std::copy(std::begin(s), std::end(s),
std::raw_storage_iterator<std::string*, std::string>(p));
for(std::string* i = p; i!=p+5; ++i) {
std::cout << *i << 'n';
i->~basic_string<char>();
}
std::return_temporary_buffer(p);
}