我想重写一个分配器,以便跟踪一些有关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 ++编译代码。
提前致谢 安德烈