C++ 如何实现一个大小受限的stl类容器?

C++ 如何实现一个大小受限的stl类容器?,c++,stl,refactoring,C++,Stl,Refactoring,在重构时,我想更改一个数组,其中条目被添加到std::vector,但为了兼容性(持久性、降级等),它仍然需要有一个上限。 最好的方法(优雅的、类似stl的、有限的额外代码)是什么,以拥有一个大小有限的类似stl的容器,这样您就知道插入条目失败了 编辑: 澄清一下:我想要一个类似stl的容器,它的开头是空的,可以填充条目,也可以删除条目,并且可以在填充的条目上进行迭代,但不允许输入超过50个条目,所以几乎像是一个连续的container,但有一个上限 您可以创建拒绝分配大于给定大小的数组的自定义

在重构时,我想更改一个数组,其中条目被添加到std::vector,但为了兼容性(持久性、降级等),它仍然需要有一个上限。
最好的方法(优雅的、类似stl的、有限的额外代码)是什么,以拥有一个大小有限的类似stl的容器,这样您就知道插入条目失败了

编辑

澄清一下:我想要一个类似stl的容器,它的开头是空的,可以填充条目,也可以删除条目,并且可以在填充的条目上进行迭代,但不允许输入超过50个条目,所以几乎像是一个连续的container,但有一个上限

您可以创建拒绝分配大于给定大小的数组的自定义分配器(例如,从
std::allocator
派生)

注意,在向结果对象添加东西之前,需要调用结果对象上的
reserve(vector\u max)
。我对C++标准提出了一个缺陷,因为这个要求应该是不必要的(它是在GCC的最新版本上)。
模板
结构有限\u alloc:std::分配器{
size\u t max\u size()常量{return N;}
typename std::分配器::指针分配(大小){
if(n
有限分配(有限分配常数&){}
模板
结构重新绑定{typedef limited_alloc other;};
};
枚举{vector_max=40};
模板
结构有限向量{
typedef std::vector>类型;
};
void f(){
有限向量:x型;
x、 储备(向量_max);
x、 赋值(向量_max+1,3);//抛出。
}

自定义vector类以施加上限。 也许,您可以公开一个新的api,该api将根据上限检查大小,如果超出上限,则返回false,否则请调用常规插入方法。

查看

作为普通阵列的替代,STL提供了类std::vector。然而,std::vector提供了动态数组的语义。因此,它管理数据,以便能够更改元素的数量。如果只需要具有静态大小的数组,这会导致一些开销


看看boost::array


编辑:for add/delete boost::optional可以用作boost::array的元素类型。

一个简单的解决方案是将向量封装在您自己的有限大小容器中。您可以使用私有组合或私有继承——请注意,私有继承模型是根据实现的,并且没有公共继承的一些缺点

编辑:具有私有继承的解决方案草图

template <typename T, unsigned int N>
class fixed_vector : std::vector<T>
{
    typedef std::vector<T> vector_type;
public:
    typedef typename vector_type::reference reference;
    typedef typename vector_type::const_reference const_reference;
    typedef typename vector_type::iterator iterator;
    typedef typename vector_type::const_iterator const_iterator;
    typedef typename vector_type::value_type value_type;
    typedef typename vector_type::size_type size_type;

    fixed_vector() : vector_type() {}
    fixed_vector( size_type size, value_type const & value = value_type() )
       : vector_type(size,value)
    {}      

    void push_back( value_type v ) {
        ensure_can_grow();
        vector_type::push_back( v );
    }
    iterator insert( iterator position, value_type const & v ) {
        ensure_can_grow();
        vector_type::insert( position, v );
    }
    void reserve( size_type size ) {
        if ( size > N ) throw std::invalid_argument();
        vector_type::reserve( size );
    }
    size_type capacity() const {
        // In case the default implementation acquires by default 
        // more than N elements, or the vector grows to a higher capacity
        return std::min( vector_type::capacity(), N );
    }
    // provide other insert methods if required, with the same pattern
    using vector_type::begin;
    using vector_type::end;
    using vector_type::operator[];
    using vector_type::erase;
    using vector_type::size;
    using vector_type::empty;
private:
    void ensure_can_grow() const {
        // probably a different exception would make sense here: 
        if ( this->size() == N ) throw std::bad_alloc();
    }
};
模板
类固定向量:std::vector
{
typedef std::矢量_类型;
公众:
typedef typename vector_type::reference引用;
typedef typename vector_type::const_reference const_reference;
typedef typename vector_type::迭代器迭代器;
typedef typename vector_type::const_迭代器const_迭代器;
typedef typename vector_type::value_type value_type;
typedef typename vector_type::size_type size_type;
固定向量():向量类型(){}
固定向量(大小\u类型大小,值\u类型常量&value=value\u类型()
:矢量_类型(大小、值)
{}      
无效推回(v型值){
确保你能成长();
向量类型:推回(v);
}
迭代器插入(迭代器位置,值类型常量&v){
确保你能成长();
向量类型::插入(位置,v);
}
空位预留(尺寸\类型尺寸){
如果(大小>N)抛出std::无效的_参数();
向量类型::保留(大小);
}
大小\类型容量()常数{
//如果默认实现默认获取
//超过N个元素,或向量增长到更大容量
返回std::min(vector_type::capacity(),N);
}
//如果需要,提供具有相同模式的其他插入方法
使用vector_type::begin;
使用vector_type::end;
使用向量_type::运算符[];
使用向量类型::擦除;
使用vector_type::size;
使用vector_type::empty;
私人:
void确保可以增长()常量{
//这里可能有一个不同的例外:
如果(this->size()==N)抛出std::bad_alloc();
}
};
那里有很多人挥手
std::vector
获取更多可以添加到立面的参数。如果您需要任何其他方法或typedef,您可以使用声明将它们引入范围,重新定义typedef,或者使用特定测试实现适配器

此外,在这个实现中,大小是一个编译时常量,但将其修改为构造函数参数非常简单。

看看我刚才找到的。我想这正是你想要的


它是在非常自由的boost许可下发布的,所以你可以用它做任何事情

有一个固定大小的数组可以吗?您可以使用来自C++ Tr1-STD::数组没有添加/删除功能,所以应该添加这个。还需要有一种方法来检查添加是否失败。你在寻找循环缓冲区吗?@John:循环缓冲区往往会覆盖最旧的条目(boost中的默认值)。当数组已满时,我需要停止。@stefaanv:那么,如果用户将新元素推入一个完整的容器,会发生什么情况?如果您的上限很低,也就是说。因此,我仍然需要自定义数组以提供添加/删除功能?向量的容量增长方式不同于其在用大小(例如,一次推送)
template <typename T, unsigned int N>
class fixed_vector : std::vector<T>
{
    typedef std::vector<T> vector_type;
public:
    typedef typename vector_type::reference reference;
    typedef typename vector_type::const_reference const_reference;
    typedef typename vector_type::iterator iterator;
    typedef typename vector_type::const_iterator const_iterator;
    typedef typename vector_type::value_type value_type;
    typedef typename vector_type::size_type size_type;

    fixed_vector() : vector_type() {}
    fixed_vector( size_type size, value_type const & value = value_type() )
       : vector_type(size,value)
    {}      

    void push_back( value_type v ) {
        ensure_can_grow();
        vector_type::push_back( v );
    }
    iterator insert( iterator position, value_type const & v ) {
        ensure_can_grow();
        vector_type::insert( position, v );
    }
    void reserve( size_type size ) {
        if ( size > N ) throw std::invalid_argument();
        vector_type::reserve( size );
    }
    size_type capacity() const {
        // In case the default implementation acquires by default 
        // more than N elements, or the vector grows to a higher capacity
        return std::min( vector_type::capacity(), N );
    }
    // provide other insert methods if required, with the same pattern
    using vector_type::begin;
    using vector_type::end;
    using vector_type::operator[];
    using vector_type::erase;
    using vector_type::size;
    using vector_type::empty;
private:
    void ensure_can_grow() const {
        // probably a different exception would make sense here: 
        if ( this->size() == N ) throw std::bad_alloc();
    }
};