C++ 具有普通STL接口的最大大小阵列,类似于boost::array

C++ 具有普通STL接口的最大大小阵列,类似于boost::array,c++,boost,C++,Boost,boost中是否有一个类似于array的类,它是一个带有数组的类似于POD的类型,但在容器中提供了数量可变的项。也就是说,我想说数组最多有10项,但在任何给定时刻都可能包含0到10项 boost::array不幸地将size()固定为常量N,因此它不能作为向量的替代品。特别是我希望该结构的读者不要知道它是一个静态数组,他们可以像其他容器一样使用begin()和end() 显然,push_back()如果超出容量,则必须通过异常 最好使用boost中已有的东西 注意:它必须是类似于POD的数据类型

boost中是否有一个类似于array的类,它是一个带有数组的类似于POD的类型,但在容器中提供了数量可变的项。也就是说,我想说数组最多有10项,但在任何给定时刻都可能包含0到10项

boost::array
不幸地将
size()
固定为常量
N
,因此它不能作为向量的替代品。特别是我希望该结构的读者不要知道它是一个静态数组,他们可以像其他容器一样使用
begin()
end()

显然,
push_back()
如果超出容量,则必须通过异常

最好使用
boost
中已有的东西

注意:它必须是类似于POD的数据类型。为清晰起见,包含内容的整个类似数组的对象(其本身将按类似于POD的类型)必须是类似于POD的。这是出于序列化/复制原因(以及与该序列化/复制相关的性能)

我所说的类豆荚是指:

  • 具有编译时常量大小
  • 可以安全地记住

对于那些说这行不通或不可能的人。这没有什么独创性。
boost::array
是一种类似于POD的类型。只需要为当前大小添加一个额外的字段,就可以使其成为我想要的。我正在寻找一个已经存在的实现(并因此得到了正确的测试/维护)。

您说“它必须是POD数据类型”。您的收藏不需要是POD吗

如果数据类型为POD,则
std::vector
提供了所需的功能,许多实现将优化数据为POD的复制/移动语义

为什么需要替换向量

尽管直接回答这个问题:我怀疑有这样一个类的提升,因为向量(保持大小)已经达到了目的,因此,他们将不考虑它的真正需要。code>boost::array没有不同大小和容量的概念

如果vector或boost::array超出了您设置的容量,您可以很容易地编写自己的包装器类来抛出它

现在,如果你要实现它,最有可能的方法是一个包含向量、boost数组或正则数组的类,然后实现你所有的函数。我想说这是直观的,但是可能有一个更聪明的解决方案来重载分配器,而不是在内部保存boost::array并使用它来进行向量的“分配”。如果分配器的容量不足(因为其内部数组已满),则抛出(可能是bad_alloc)。然后,用户只需将该类用作向量,并可以调用其所有函数,但如果他们试图将向量增长到大于其大小,则您将抛出该类

由于vector的性质,您的分配器不应作为堆工作,从而释放某些对象。您只需维护一个连续的缓冲区

关于POD或接近POD的问题,向量中的实际数据保证是一个连续的缓冲区,并且您的分配器在内部使用boost::array,因此它将是连续的。如果您想要序列化,那么boost::serialize已经可以正确处理向量了


整个集合、容器和 内容,必须是单个 固定大小的内存:在 编译时

您的分配器可能如下所示:

typename< typename T, size_t SIZE >
class Allocator
{
    struct Data
    {
        size_t num_used;
        T[SIZE] data;
    } d;

public:
    // implement allocator's methods
};
typename
类分配器
{
结构数据
{
使用的大小和数量;
T[SIZE]数据;
}d;
公众:
//实现分配器的方法
};
实现你说的“它必须是一个POD数据类型”。您的收藏不需要是POD吗

如果数据类型为POD,则
std::vector
提供了所需的功能,许多实现将优化数据为POD的复制/移动语义

为什么需要替换向量

尽管直接回答这个问题:我怀疑有这样一个类的提升,因为向量(保持大小)已经达到了目的,因此,他们将不考虑它的真正需要。code>boost::array没有不同大小和容量的概念

如果vector或boost::array超出了您设置的容量,您可以很容易地编写自己的包装器类来抛出它

现在,如果你要实现它,最有可能的方法是一个包含向量、boost数组或正则数组的类,然后实现你所有的函数。我想说这是直观的,但是可能有一个更聪明的解决方案来重载分配器,而不是在内部保存boost::array并使用它来进行向量的“分配”。如果分配器的容量不足(因为其内部数组已满),则抛出(可能是bad_alloc)。然后,用户只需将该类用作向量,并可以调用其所有函数,但如果他们试图将向量增长到大于其大小,则您将抛出该类

由于vector的性质,您的分配器不应作为堆工作,从而释放某些对象。您只需维护一个连续的缓冲区

关于POD或接近POD的问题,向量中的实际数据保证是一个连续的缓冲区,并且您的分配器在内部使用boost::array,因此它将是连续的。如果您想要序列化,那么boost::serialize已经可以正确处理向量了


整个集合、容器和 内容,必须是单个 固定大小的内存:在 编译时

您的分配器可能如下所示:

typename< typename T, size_t SIZE >
class Allocator
{
    struct Data
    {
        size_t num_used;
        T[SIZE] data;
    } d;

public:
    // implement allocator's methods
};
typename
类分配器
{
结构数据
{
使用的大小和数量;
T[SIZE]数据;
}d;
公众:
//实现分配器的
#pragma once
#include <boost/array.hpp>

template<class T, class IndexType, IndexType MaximumSize>
class StaticVector : public boost::array<T, MaximumSize>
{
  IndexType count;
public:
  StaticVector() : count(0) {}
  inline void add(const T& value)
  {
    if (this->full())
      throw std::runtime_error("Can't add (size = %d)\n", MaximumSize);
    (*this)[this->count] = value;
    this->count++;
  }

  inline void addDirty()
  {
    if (this->full())
      throw std::runtime_error("Can't add, container full.");
    this->count++;
  }

  inline void remove(IndexType index)
  {
    if (this->count > 1)
      (*this)[index] = (*this)[count - 1];
    this->count--;
  }

  inline void clear() { this->count = 0; }
  inline IndexType size() const { return this->count; }
  inline bool empty() const { return this->count == 0; }
  inline bool full() const { return this->count == MaximumSize; }
  inline const T& back() const { return (*this)[this->count - 1]; }
  inline T& back() { return (*this)[this->count - 1]; }

  inline typename boost::array<T, MaximumSize>::iterator  end()       { return this->elems + count; }
  inline typename boost::array<T, MaximumSize>::const_iterator  end() const { return this->elems + count; }
  inline typename boost::array<T, MaximumSize>::const_iterator cend() const { return this->elems + count; }
};