自定义分配器对std :: map失败

时间:2014-01-09 20:24:35

标签: c++ linux gcc stl g++

我尝试将自定义分配器与C ++ STL容器一起使用,并且它适用于vector,但是因地图而失败。关于mmap_allocator<std::_Rb_tree_node<std::pair<const int, int> > >并且没有像我期待的那样使用mmap_allocator<std::pair<const int, int> >的一些奇怪错误

In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/map:60,
                 from 4.cpp:2:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h: In member function ‘_Alloc std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::get_allocator() const [with _Key = int, _Val = std::pair<const int, int>, _KeyOfValue = std::_Select1st<std::pair<const int, int> >, _Compare = std::less<int>, _Alloc = mmap_allocator<std::pair<const int, int> >]’:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:383:   instantiated from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_destroy_node(std::_Rb_tree_node<_Val>*) [with _Key = int, _Val = std::pair<const int, int>, _KeyOfValue = std::_Select1st<std::pair<const int, int> >, _Compare = std::less<int>, _Alloc = mmap_allocator<std::pair<const int, int> >]’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:972:   instantiated from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_erase(std::_Rb_tree_node<_Val>*) [with _Key = int, _Val = std::pair<const int, int>, _KeyOfValue = std::_Select1st<std::pair<const int, int> >, _Compare = std::less<int>, _Alloc = mmap_allocator<std::pair<const int, int> >]’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:614:   instantiated from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::~_Rb_tree() [with _Key = int, _Val = std::pair<const int, int>, _KeyOfValue = std::_Select1st<std::pair<const int, int> >, _Compare = std::less<int>, _Alloc = mmap_allocator<std::pair<const int, int> >]’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_map.h:87:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:354: error: no matching function for call to ‘mmap_allocator<std::pair<const int, int> >::mmap_allocator(const mmap_allocator<std::_Rb_tree_node<std::pair<const int, int> > >&)’
4.cpp:37: note: candidates are: mmap_allocator<T>::mmap_allocator(const mmap_allocator<T>&) [with T = std::pair<const int, int>]
4.cpp:36: note:                 mmap_allocator<T>::mmap_allocator() [with T = std::pair<const int, int>]

以下是代码:

#include <vector>
#include <map>
#include <stdio.h>

static size_t alloc;

        template <typename T>
        class mmap_allocator: public std::allocator<T>
        {
public:
                typedef size_t size_type;
                typedef T* pointer;
                typedef const T* const_pointer;

                template<typename _Tp1>
                struct rebind
                {
                        typedef mmap_allocator<_Tp1> other;
                };

                pointer allocate(size_type n, const void *hint=0)
                {
                        fprintf(stderr, "Alloc %d bytes.\n", n);
                        alloc += n;
                        return std::allocator<T>::allocate(n, hint);
                }

                void deallocate(pointer p, size_type n)
                {
                        fprintf(stderr, "Dealloc %d bytes (%p).\n", n, p);
                        alloc -= n;
                        return std::allocator<T>::deallocate(p, n);
                }

                mmap_allocator() throw(): std::allocator<T>() { fprintf(stderr, "Hello allocator!\n"); }
                mmap_allocator(const mmap_allocator &a) throw(): std::allocator<T>(a) { }
                ~mmap_allocator() throw() { }
        };

int main(){

std::vector<int, mmap_allocator<int> > int_vec(1024, 0, mmap_allocator<int>());
std::map<int, int, std::less<int>,  mmap_allocator<std::pair<int,int> > >  x;
x[1] = 2;
printf("s=%lu\n", alloc);
return 0;
}

Linux,gcc 4.4.6。

1 个答案:

答案 0 :(得分:0)

我还没有尝试修复它,但似乎你还没有定义一个构造函数,它使用不同的模板参数进行分配器实例化。也就是说,你错过了像

这样的东西
template <typename T>
    template <typename O>
mmap_allocator<T>::mmap_allocator(mmap_allocator<O> const& other) {
    ...
}

从它的外观来看,错误源于尝试构造从rebind获得的分配器类型以及其他分配器。