如何实现尺寸限制的stl类容器? [英] How should a size-limited stl-like container be implemented?

查看:137
本文介绍了如何实现尺寸限制的stl类容器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

重构时,我想更改一个数组,其中条目添加到std :: vector,但是为了兼容性(持久性,降级,...),它仍然需要有一个上限。

什么是最好的方式(优雅,stl,有限的额外代码)有一个限制大小的stl类容器,所以你知道插入一个条目失败?



编辑

澄清:我想要一个类似stl的容器,开始空,你可以填写条目,可能删除条目,超过填充的条目,但是不允许放入超过例如50个条目,所以几乎像一个顺序的禁忌,但有一个上限。

解决方案

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



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

  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 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 {
//如果默认实现默认获取
//超过N个元素,或者向量增长到更高的容量
return std :: min(vector_type :: capacity(),N);
}
//如果需要,提供其他插入方法,使用相同的模式
使用vector_type :: begin;
using vector_type :: end;
using vector_type :: operator [];
using vector_type :: erase;
使用vector_type :: size;
using vector_type :: empty;
private:
void ensure_can_grow()const {
//可能不同的异常在这里是有意义的:
if(this-> size()== N)throw std :: bad_alloc();
}
};

有很多的挥手有... ... std: :vector 获取可以添加到外观的更多参数。如果你需要任何其他的方法或typedef,你可以使用使用 c>声明,重新定义typedef或实现与您的特定测试的适配器。 / p>

此外,在这个实现中,size是一个编译时常量,但将它修改为一个构造函数参数很容易。


While refactoring, I wanted to change an array where entries are added to an std::vector, but for compatibility (persistency, downgrading,...), it still needs to have an upper limit.
What is the best way (elegant, stl-like, limited extra code) to have an stl-like container which is limited in size, so you know that inserting an entry fails?

Edit:
To clarify: I would like an stl-like container, that starts empty, that you can fill with entries and possibly remove entries and that iterate over the filled-in entries, but that doesn't allow to put in more than e.g. 50 entries, so almost like a sequential contrainer, but with an upper-limit.

解决方案

A simple solution would be encapsulating a vector inside your own limited size container. You could use private composition or private inheritance --note that private inheritance models implemented in terms of and does not have some of the shortcomings of public inheritance.

EDIT: Sketch of the solution with private inheritance

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();
    }
};

There is quite a bit of hand-waving there... std::vector take more arguments that could be added to the façade. If you need any of the other methods or typedefs, you can just bring them into scope with a using declaration, redefine the typedef, or implement the adaptor with your particular test.

Also, in this implementation the size is a compile time constant, but it would be really simple to modify it into a constructor parameter.

这篇关于如何实现尺寸限制的stl类容器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆