简体   繁体   English

有没有办法限制STL :: map容器的最大大小?

[英]Is there a way to cap the max size on a STL::map container?

My application can only process up to a certain number of entry in the map structure, how do I specify that limit in my code so that my code does not get overwhelmed (for lack of better term). 我的应用程序只能处理map结构中的一定数量的条目,如何在我的代码中指定该限制,以免我的代码不知所措(因为缺少更好的术语)。 Is there a way to specify the max limit when defining the variable of type map? 定义类型map的变量时,是否可以指定最大限制?

Thanks 谢谢

There's no way to set a limit when instantiating the map, though I supposed you could have your own safe guard when accessing it. 实例化地图时,没有办法设置限制,尽管我认为访问地图时可以拥有自己的安全防护。 For example: 例如:

if (mymap.find(a) == mymap.end() and mymap.size() >= MAX_MAP_ALLOWED) {
    throw (runtime_error("map limit exceeded"));
} else {
    mymap[a] = b;
}

You could possibly create your own map class that encapsulates these checks. 您可以创建自己的地图类来封装这些检查。

The stl containers also take an ' allocator ' as a (defaulted) parameter. stl容器还使用“ 分配器 ”作为(默认)参数。 This allocator is the container's means to allocate new space for it's data. 该分配器是容器为其数据分配新空间的方法。

If you define a 'capped' allocator (sounds simple, hey?), you're there. 如果您定义了一个“上限”分配器(听起来很简单,嘿?),那么您就在那里。

EDIT - In some fora, I found that the allocators, though initially intended stateless, can be statefull on most (modern) compilers. 编辑-在某些论坛上,我发现分配器尽管最初打算是无状态的,但在大多数(现代)编译器上可能是有状态的。 That's why I carry on on this. 这就是为什么我继续这样做。 It's quite cumbersome, though, to do it this way, and probably way more easy and comprenensible to aggregate your map type in a cappedmap adapter. 但是,以这种方式进行操作非常麻烦,并且可能更容易和容易理解,将您的地图类型聚合到cappedmap适配器中。

It took me a lot of moments here and there, but here I got a compiling, capped, example: 我花了很多时间在这里和那里,但是在这里,我得到了一个编译的,有上限的示例:

// 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;

The actual code of the capped allocator delegates to the allocator member: 上限分配器的实际代码委托给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;
    };

};

This allocator can be used like this: 该分配器可以这样使用:

// 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;
}

Note: not thoroughly tested. 注意:未经彻底测试。 It's just an idea. 这只是一个主意。

After trying out the idea of a capped allocator, I think it's way more straightforward to aggregate an std::map (note: not inherit-from! At least not publicly) in a cappedadaptor . 在尝试了上限分配器的想法之后,我认为在cappedadaptor聚集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();
     }
   }
   ...
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM