重写分配器

时间:2015-05-22 22:41:18

标签: c++ stl allocator

我想重写一个分配器,以便跟踪一些有关STL容器的统计信息。 例如,我想找到容器和元素的类型。 所以我写了下面的代码。

#include <vector>
#include <map>
#include <iostream>
#include <typeinfo>

template<class T, class Container, class BaseAllocator = std::allocator<T> >
//template<class T,  class BaseAllocator = std::allocator<T> >
class MyAllocator : public BaseAllocator {
public:
    typedef typename BaseAllocator::pointer pointer;
    typedef typename BaseAllocator::size_type size_type;  

    MyAllocator() throw(): BaseAllocator() {}  // default CTOR

    MyAllocator(const MyAllocator& b) throw() : BaseAllocator(b) {}  // copy ctor

    template <class V>                                            // generic ctor
    MyAllocator(const V& b) throw() : BaseAllocator(b) {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        }    

   // template <class V>                      // generic copy ctor
   // MyAllocator(const MyAllocator<V>& b) throw() : BaseAllocator(b) {std::cout << __PRETTY_FUNCTION__ << std::endl;}    

#if __cplusplus >= 201103L    
    MyAllocator(MyAllocator&& b) throw() : BaseAllocator(b) {}
#endif    

    template<class U> struct rebind {
        typedef MyAllocator<U,Container,typename BaseAllocator::template rebind<U>::other> other;
        //typedef MyAllocator<U,typename BaseAllocator::template rebind<U>::other> other;
    };
/*
    template <class U>
    MyAllocator(const typename MyAllocator::template rebind<U>::other& b) throw() : BaseAllocator(b)
    {}
 */
    ~MyAllocator() {}

    pointer allocate(size_type n) {
        std::cout << "allocate" << std::endl;
        pointer r = BaseAllocator::allocate(n);
        return r;
    }

    void deallocate(pointer p, size_type n) throw() {
        std::cout << "deallocate" << std::endl;
        BaseAllocator::deallocate(p, n);
    }

#if __cplusplus >= 201103L
      template<typename _Up, typename... _Args>
        void construct(_Up* __p, _Args&&... __args)
      { 
        std::cout << "construct c++11 " << typeid(T).name() <<std::endl;
        std::cout << "container c++11 " << typeid(Container).name() <<std::endl;
        ::new((void *)__p) _Up(std::forward<_Args>(__args)...);        
      }

      template<typename _Up>
      void destroy(_Up* __p) { __p->~_Up(); }
#else
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 402. wrong new expression in [some_] allocator::construct
      void construct(pointer __p, const T& __val)
      {
          std::cout << "construct c++03 " << typeid(T).name() <<std::endl;
          std::cout << "container c++03 " << typeid(Container).name() <<std::endl;
          ::new((void *)__p) T(__val); 
      }
#endif
};

typedef MyAllocator<std::pair<char,int>,std::map<char,int> > allocMap;
typedef std::map<char,int,std::less<char>,allocMap> trackmap;

typedef MyAllocator<double,std::vector<double> > allocVect;
typedef std::vector<double,allocVect> trackvector;


/*
typedef MyAllocator<std::pair<char,int> > allocMap;
typedef std::map<char,int,std::less<char>,allocMap> trackmap;
typedef MyAllocator<double> allocVect;
typedef std::vector<double,allocVect> trackvector;
*/


int main()
{

    std::cout << "*************** MAP ***************" << std::endl;
    trackmap first;
    first['a']=10;
    first.insert(std::pair<char,int>('m',2));
  std::cout << "*************** VECTOR ***************" << std::endl;
  trackvector vett(1,100);
  vett.push_back(4);
  std::cout << "*************** cccccccccccc ***************" << std::endl;   
}

我使用typename Container来获取有关容器类型的信息。 我注意到通过分析编译错误,工作,类通用构造函数的需要。 为了重写分配器,我使用了STL文件中的类std :: allocator的定义(allocator.h,bits / c ++ allocator.h ..)。 在那个定义中,我没有找到类似的CTOR。该类具有默认的ctor,copy ctor和generic copy ctor(进行强制转换)。 此外,我测试了如果我使用没有模板参数“Container”的同一个类,该类也可以正常工作,没有通用的CTOR。

有人可以解释原因吗?为什么我需要通用的CTOR?

说,这是肯定的吗?我的意思是,通过使用这个类可以保证STL容器的行为不会被修改吗?

使用g ++编译代码。

提前致谢 安德烈

0 个答案:

没有答案