在我写自己之前,我会问你们所有人.
我正在寻找一个几乎完全像STL向量的C++类,但是将数据存储到堆栈中的数组中.某种类型的STL分配器类也可以工作,但我试图避免任何类型的堆,甚至是静态分配的每线程堆(尽管其中一个是我的第二选择).堆栈效率更高.
它需要几乎替代使用向量的当前代码.
对于我自己要写的东西,我在考虑这样的事情:
char buffer[4096];
stack_vector<match_item> matches(buffer, sizeof(buffer));
或者类可以在内部分配缓冲区空间.然后它看起来像:
stack_vector<match_item, 256> matches;
我认为如果空间不足,它会抛出std :: bad_alloc,尽管这不应该发生.
更新
使用Chromium的stack_container.h效果很好!
我之所以没想过这样做的原因是我总是忽略了STL集合构造函数的allocator对象参数.我已经使用了几次模板参数来做静态池,但是我从未见过代码或编写任何实际使用过对象参数的代码.我学到了新东西.很酷!
代码有点乱,由于某种原因,GCC强迫我将分配器声明为实际项而不是将其构造为vector的allocator参数.它来自这样的事情:
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 ); …我有一个非常相似的问题
如何使用glibc的字符串实现在堆栈上分配std :: string?
但我认为值得重新询问.
我想要一个std::string溢出到免费商店的本地存储.std::basic_string提供一个分配器作为模板参数,所以看起来要做的就是用本地存储编写一个分配器并用它来参数化basic_string,如下所示:
std::basic_string<
char, 
std::char_traits<char>, 
inline_allocator<char, 10> 
> 
x("test");
我试着编写一个inline_allocator可以按照你期望的方式工作的类:它为存储保留10个字节,如果basic_string需要超过10个字节,则调用::operator new().我无法让它发挥作用.在执行上面的代码行的过程中,我的GCC 4.5标准字符串库调用了复制构造函数inline_allocator4次.我不清楚是否有一种合理的方法来编写复制构造函数inline_allocator.
在另一个StackOverflow线程中,Eric Melski将此链接提供给Chromium中的一个类:
http://src.chromium.org/svn/trunk/src/base/stack_container.h
这很有趣,但它不是替代品std::string,因为它包装std::basic_string在一个容器中,所以你必须调用一个重载operator->()来获取std::basic_string.
我找不到任何其他解决方案.难道没有好的解决方案吗?如果这是真的,那么这些std::basic_string和std::allocator概念是否存在严重缺陷?我的意思是,似乎这应该是一个非常基本和简单的用例std::basic_string和std::allocator.我想这个std::allocator概念主要是为游泳池设计的,但我认为它也应该涵盖这个.
看起来像C++ 0x中的rvalue-reference移动语义可能使写入成为可能inline_allocator,如果重写了字符串库,那么basic_string使用其分配器的移动构造函数而不是复制构造函数.有谁知道这个结果的前景如何?
我的应用程序需要每秒构建一百万个微小的ASCII字符串,所以我最终编写了自己的固定长度字符串类Boost.Array,它工作正常,但这仍然困扰着我.
在大约十年前的一个项目中,我们发现std::vector动态分配导致了严重的性能损失.在这种情况下,它分配了许多小向量,因此快速解决方案是编写一个类似于向量的类,包装在基于堆栈的预分配char数组中,用作其容量的原始存储.结果是static_vector<typename T, std::size_t Max>.如果您了解一些基础知识,这样的事情很容易写,你可以在网上找到很多这样的野兽.事实上,现在也有一个提升.
现在在嵌入式平台上工作,我们碰巧需要一个static_basic_string.这将是一个字符串,它预先在堆栈上分配固定的最大内存量,并将其用作容量.
起初我认为这应该相当容易(static_vector毕竟它可以基于现有的),但再看看std::basic_string界面我不再那么肯定了.它比std::vector界面更复杂.特别是实现find()功能系列std::basic_string不仅仅是一项繁琐的工作.
这让我再次思考.毕竟,这就是创建分配器的原因:基于new和delete使用其他方法替换分配.但是,要说分配器接口不实用将是轻描淡写.有一些文章在那里解释它,但有一个原因,我在过去的15年中看到这么少的本土分配器.
所以这是我的问题:
如果你必须实现一个basic_string相似的,你会怎么做?
static_basic_string?std::basic_string?与往常一样,对我们来说存在相当重要的限制:在嵌入式平台上,我们与GCC 4.1.2绑定,因此我们只能使用C++ 03,TR1和boost 1.52.