处理stl容器的大小

Dealing with size of stl containers

本文关键字:stl 处理      更新时间:2023-10-16

我正在重写一个通用库,该库是我在学习STL之前编写的。它一直使用C样式数组。在许多地方都有这样的代码:

unsigned short maxbuffersize; // Maximum possible size of the buffer. Can be set by user.
unsigned short buffersize; // Current size of the buffer.
T *buffer; // The buffer itself.

我做的第一件事就是这样更改代码:

unsigned short maxbuffersize;
unsigned short buffersize;
std::vector<T> buffer;

然后:

typedef unsigned short BufferSize;
BufferSize maxbuffersize;
BufferSize buffersize;
std::vector<T> buffer;

然后我觉得我做了一件非常糟糕的事情,应该重新考虑我的编码风格。起初,BufferSize对于一种类型来说似乎是一个非常糟糕的名字,但后来各种奇怪的问题开始出现。如何命名尺寸类型?我应该使用自己的类型还是从std::vector<T>::size_type继承?我应该缓存容器的大小还是一直使用size()?我应该允许用户手动设置容器的最大大小吗?如果不允许,我如何检查溢出?

我知道不可能有一刀切的方法,因此我想听听其他程序员和框架供应商使用的策略。我正在开发的库是跨平台通用的,旨在发布到公共领域并使用几十年。谢谢

我认为默认的选择应该是去掉buffersizemaxbuffersize,并始终使用buffer.size()buffer.capacity()

我建议不要缓存大小,除非您有非常具体的理由这样做,并使用探查器运行的硬数据进行备份。缓存将引入额外的复杂性,并有可能使缓存与实际内容同步。

最后,在您认为有必要进行边界检查的地方,可以使用buffer.at(i)。如果i越界,这将引发异常。

通常,我建议使用迭代器来访问数据。当您这样做时,您通常根本不会显式调用容器的大小。这也使您不必同时使用std::vector,并且如果您稍后意识到这更适合您的需求,可以简单地更改为,例如std::list

当您使用迭代器时,对vector.size()的需求通常会大大减少。(当您确实需要它时,请使用aix所说的buffer.size()buffer.capacity()(。

例如:

typedef unsigned short BufferSize;
BufferSize maxbuffersize;
BufferSize buffersize;
std::vector<T> buffer;
for(unsigned short i = 0; i< maxbuffersize;++i)
{
  //do something with buffer[i];
}

成为

struct do_something
{
  void operator()(const T& t) 
  { 
   //do something with buffer[i]
  }
};
std::vector<T> buffer(maxbuffersize);
std::for_each(buffer.begin(), buffer.end(), do_something());

它稍微干净一点。

保持大小对may结构很有用,但对数组/向量来说有点多余,因为大小保证是最终索引+1。如果你担心会超过末尾,那么像前面提到的迭代器方法可以解决这个问题,以及关于可能的比较大小的大多数其他问题,等等;

用API在一个头中定义所有类型及其大小是非常标准的,它为不同的平台和编译器设置它们。。。查看具有LONG、ULONG、DWORD等定义的窗口。旧的"C"约定是在它们前面加上一个唯一的名称或首字母缩写,如MYAPI_SIZETYPE。它很冗长,但避免了任何跨平台的混乱或编译器问题。