我的应用程序只能在地图结构中处理最多一定数量的条目,如何在我的代码中指定该限制,以便我的代码不会被淹没(因为缺少更好的术语)。有没有办法在定义map类型的变量时指定最大限制?
由于
答案 0 :(得分:3)
实例化地图时无法设置限制,但我认为您在访问地图时可以拥有自己的安全防范。例如:
if (mymap.find(a) == mymap.end() and mymap.size() >= MAX_MAP_ALLOWED) {
throw (runtime_error("map limit exceeded"));
} else {
mymap[a] = b;
}
您可以创建自己的地图类来封装这些检查。
答案 1 :(得分:1)
stl容器还将“allocator”作为(默认)参数。这个分配器是容器为其数据分配新空间的手段。
如果你定义一个'上限'分配器(听起来很简单,嘿?),你就在那里。
编辑 - 在一些论坛中,我发现分配器虽然最初是无状态的,但在大多数(现代)编译器上都可以是有状态的。这就是我继续这个的原因。但是,这样做非常麻烦,并且可能更容易和更易于在cappedmap适配器中聚合地图类型。我在这里和那里花了很多时间,但在这里我有一个编译,上限,例子:
// an allocator with maximally MAX elements.
template< typename T, size_t MAX = 5 >
struct AllocateCapped {
// reuses an existing allocator
typedef std::allocator<T> tallocator;
typedef typename tallocator::value_type value_type;
typedef typename tallocator::pointer pointer;
typedef typename tallocator::reference reference;
typedef typename tallocator::const_pointer const_pointer;
typedef typename tallocator::const_reference const_reference;
typedef typename tallocator::size_type size_type;
typedef typename tallocator::difference_type difference_type;
上限分配器的实际代码委托给allocator
成员:
size_t free;
tallocator allocator;
AllocateCapped():free(MAX){
printf("capped");
}
template<typename T2>
AllocateCapped( const AllocateCapped<T2>& other ){}
pointer allocate( size_type n, const_pointer hint = 0) {
if( !free ) throw std::bad_alloc();
free-=n;
return allocator.allocate( n, hint );
}
void deallocate( pointer p, size_type n ) {
free+=n;
allocator.deallocate(p,n);
}
size_type max_size() const { return free; }
void construct( pointer p, const_reference val ) {
return allocator.construct(p,val);
}
void destroy( pointer p ) { allocator.destroy(p); }
template<class _Other>
struct rebind
{ // convert this type to _ALLOCATOR<_Other>
typedef typename AllocateCapped<_Other> other;
};
};
这个分配器可以像这样使用:
// example structure
struct s {
int i;
s():i(){}
s(int i):i(i){}
};
int main(int argc, char* argv[]) {
typedef AllocateCapped< std::pair<const int, s> > talloc;
talloc a;
talloc::pointer p = reinterpret_cast<talloc::pointer>( a.allocate(1,0) );
a.construct(p, talloc::value_type() );
a.destroy(p);
a.deallocate(p, 1 );
std::map<int , s, std::less<int>, talloc > m;
std::vector<int, AllocateCapped<int> > v;
for( int i = 0; i != 4; ++i ) {
m[i]=s(i);
v.push_back(i);
}
m[5]=s(5); // throws
v.push_back(5); // throws
return 0;
}
注意:未经过彻底测试。这只是一个想法。
答案 2 :(得分:1)
在尝试了上限分配器的想法后,我认为在std::map
中聚合cappedadaptor
(注意:不是继承 - 至少不公开)的方式更直接。
template<typename tKey, typename tVal> class cappedmap {
typedef std::map<tKey,tVal> tmap;
tmap mymap;
cappedmap(size_t amax):mymax(amax){}
// adapt the map interface
pair<tmap::iterator,bool> insert( tmap::value_type kv ) {
if( mymap.size() > mymax ) throw myexcept();
return mymap.insert(kv);
}
tVal operator[]( tKey k ) {
tVal v = mymap[k];
if( mymap.size() > mymax ) {
mymap.remove(k)
throw myexcept();
}
}
...
};