В STL контейнеры также принимают 'allocator' в качестве (дефолт) параметра. Этот распределитель является средством контейнера для размещения нового пространства для его данных.
Если вы определили «ограниченный» распределитель (звучит просто, эй?), Вы там.
EDIT - На некоторых форумах я обнаружил, что распределители, хотя первоначально планируемые апатриды, могут быть statefull для большинства (современных) компиляторов. Вот почему я продолжаю это. Это довольно громоздко, однако, сделать это таким образом, и, вероятно, проще и сложнее объединить ваш тип карты в адаптер 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 к 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;
}
Примечание: не Thor тщательно проверенный. Это просто идея.
Другое, чем не помещать больше N элементов на карту? –