本文介绍了寻找类似 C++ STL 的向量类但使用堆栈存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我自己写之前,我会问你们所有人.

Before I write my own I will ask all y'all.

我正在寻找一个 C++ 类,它几乎与 STL 向量完全一样,但将数据存储到堆栈上的数组中.某种 STL 分配器类也可以工作,但我试图避免任何类型的堆,甚至是静态分配的每线程堆(尽管其中一个是我的第二选择).堆栈更有效.

I'm looking for a C++ class that is almost exactly like a STL vector but stores data into an array on the stack. Some kind of STL allocator class would work also, but I am trying to avoid any kind of heap, even static allocated per-thread heaps (although one of those is my second choice). The stack is just more efficient.

它几乎需要替代使用向量的当前代码.

It needs to be almost a drop in replacement for current code that uses a vector.

对于我自己要写的东西,我正在考虑这样的事情:

For what I was about to write myself I was thinking of something like this:

char buffer[4096];
stack_vector<match_item> matches(buffer, sizeof(buffer));

或者类可以在内部分配缓冲区空间.然后它看起来像:

Or the class could have buffer space allocated internally. Then it would look like:

stack_vector<match_item, 256> matches;

我认为如果空间不足,它会抛出 std::bad_alloc ,尽管这不应该发生.

I was thinking it would throw std::bad_alloc if it runs out of space, although that should not ever happen.

更新

使用 Chromium 的 stack_container.h 效果很好!

Using Chromium's stack_container.h works great!

我自己没想过这样做的原因是我一直忽略了 STL 集合构造函数的分配器对象参数.我曾多次使用模板参数来做静态池,但我从未见过代码或编写任何实际使用对象参数的代码.我学到了一些新东西.很酷!

The reason I hadn't thought of doing it this way myself is that I have always overlooked the allocator object parameter to the STL collection constructors. I have used the template parameter a few times to do static pools but I'd never seen code or written any that actually used the object parameter. I learned something new. Very cool!

代码有点乱,出于某种原因,GCC 迫使我将分配器声明为实际项目,而不是将其构造为向量的分配器参数.它来自这样的事情:

The code is a bit messy and for some reason GCC forced me to declare the allocator as an actual item instead of constructing it into vector's allocator parameter. It went from something like this:

typedef std::pair< const char *, const char * > comp_list_item;
typedef std::vector< comp_list_item > comp_list_type;

comp_list_type match_list;
match_list.reserve(32);

为此:

static const size_t comp_list_alloc_size = 128;
typedef std::pair< const char *, const char * > comp_list_item;
typedef StackAllocator< comp_list_item, comp_list_alloc_size > comp_list_alloc_type;
typedef std::vector< comp_list_item, comp_list_alloc_type > comp_list_type;

comp_list_alloc_type::Source match_list_buffer;
comp_list_alloc_type match_list_alloc( &match_list_buffer );
comp_list_type match_list( match_list_alloc );
match_list.reserve( comp_list_alloc_size );

每当我宣布一个新的时,我都必须重复这一点.但它就像我想要的那样工作.

And I have to repeat that whenever I declare a new one. But it works just like I wanted.

我注意到 stack_container.h 定义了一个 StackVector,我尝试使用它.但它不从 vector 继承或定义相同的方法,所以它不是一个简单的替代品.我不想使用向量重写所有代码,所以我放弃了.

I noticed that stack_container.h has a StackVector defined and I tried using it. But it doesn't inherit from vector or define the same methods so it wasn't a drop-in replacement. I didn't want to rewrite all the code using the vector so I gave up on it.

推荐答案

您不必编写全新的容器类.您可以坚持使用 STL 容器,但更改例如 std::vector 的第二个参数,为其提供从堆栈缓冲区分配的自定义分配器.铬的作者为此编写了一个分配器:

You don't have to write a completely new container class. You can stick with your STL containers, but change the second parameter of for example std::vector to give it your custom allocator which allocates from a stack-buffer. The chromium authors wrote an allocator just for this:

https://chromium.googlesource.com/chromium/铬/+/master/base/stack_container.h

它的工作原理是在你说它有多大的地方分配一个缓冲区.您创建容器并调用 container.reserve(buffer_size);.如果超出该大小,分配器将自动从堆中获取元素(因为它是从 std::allocator 派生的,在这种情况下它将只使用标准分配器的功能).我还没有尝试过,但它看起来像是来自谷歌,所以我认为值得一试.

It works by allocating a buffer where you say how big it is. You create the container and call container.reserve(buffer_size);. If you overflow that size, the allocator will automatically get elements from the heap (since it is derived from std::allocator, it will in that case just use the facilities of the standard allocator). I haven't tried it, but it looks like it's from google so i think it's worth a try.

用法是这样的:

StackVector<int, 128> s;
s->push_back(42); // overloaded operator->
s->push_back(43);

// to get the real std::vector.
StackVector<int, 128>::ContainerType & v = s.container();
std::cout << v[0] << " " << v[1] << std::endl;

这篇关于寻找类似 C++ STL 的向量类但使用堆栈存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 12:27