如何实现尺寸限制的stl类容器? [英] How should a size-limited stl-like container be implemented?
问题描述
重构时,我想更改一个数组,其中条目添加到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();
}
};
有很多的挥手有... ... 此外,在这个实现中,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. Edit: 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 There is quite a bit of hand-waving there... 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屋! std: :vector
获取可以添加到外观的更多参数。如果你需要任何其他的方法或typedef,你可以使用使用 c>声明,重新定义typedef或实现与您的特定测试的适配器。 / p>
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?
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. 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
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.