因此,在性能敏感的应用程序中需要它的大量案例,我终于挣扎着打破了骆驼。它需要在C ++ 98中编译,因为我们的平台中至少只有一个保证符合C ++ 98标准。
希望能够更清楚地了解我想要的东西。
示例:
// This will allocate storage for 1024, and then loop 1024 times touching all of it just to place a 0 in it
std::vector< char > buffer( 1024 );
// Now read will write into that buffer, overwriting the 0s ( we payed for the fill unnecessarily )
buffer.resize( read( someSource, &buffer[0], buffer.size() ) );
这是常见的C接口,几乎与所有C库一起用于将数据写入缓冲区。在处理通常包含基元的缓冲区时会出现同样的问题。新的大小调整看起来像这样:
// Disabled for anything which doesn't pass boost::is_POD< T >, they get the standard version
void resize( size_t a_NewSize )
{
reserve( a_NewSize );
_end = _begin + a_NewSize;
}
construct_back将是一个转发构造函数,对于1个const参数,它看起来像这样(未经测试):
template< typename T1 >
void construct_back( const T1& a_Arg1 )
{
if( capacity() <= size() ) // No room
reserve( size() + 1 );
// Construct in place using Ts constructor that accepts const T1&
new (&(*end()) T( T1 );
++_end; // Account for new element
}
construct_back必须拥有所有可能数量的参数^ 2重载,这是在C ++ 98中完美转发的常见蛮力方法。
答案 0 :(得分:3)
要在向量中预分配内存,请使用vector::reserve
。这不仅适用于原始类型,也适用于所有类型。
要构建元素,您需要使用带有vector::emplace_back
的C ++ 11或Boost.Containers提供的其中一个容器。
如果你需要延迟构造(因为你的构造函数很贵)std::vector<boost::optional>
是一个很好的解决方案。
答案 1 :(得分:1)
您的编译器可能足够聪明以避免初始化。 (如果它是内联所有内容而你只在本地使用这个向量,那么推断初始化是过时的并不是太复杂。)
否则:
如果你非常关心性能,如果你还有一个固定大小的缓冲区,为什么不在堆栈上使用一个数组呢?即:
char buffer[1024];
size_t blen = read( someSource, buffer, sizeof(buffer) );
在这种情况下,您还可以避免间接到std::vector
引入的堆。
你也可以围绕它建立自己的模板容器,即:
template<typename T = char, size_t MaxSize = 1024>
struct Buffer {
static const size_t maxsize = MaxSize;
typedef T type;
type data[maxsize];
size_t len;
Buffer() : len(0) {}
};
并根据需要插入任何其他功能(使其成为STL容器)。
答案 2 :(得分:0)
v1.reserve( 200 );
使用预留可以减少调整大小的次数
在MSDN 了解有关保留的更多信息