Allocator类模板的奇怪定义(codeproject的代码),如下:解决方法
Allocator类模板的奇怪定义(codeproject的代码),如下:
// Policy driven allocator object
template <typename T, typename Policy = StandardAllocPolicy <T> , typename Traits = ObjectTraits <T> >
class Allocator : public Policy, public Traits {
private :
typedef Policy AllocationPolicy;
typedef Traits TTraits;
public : // 这里的重定义是必要的吗?
typedef typename AllocationPolicy::size_type size_type;
typedef typename AllocationPolicy::difference_type difference_type;
typedef typename AllocationPolicy::pointer pointer;
typedef typename AllocationPolicy::const_pointer const_pointer;
typedef typename AllocationPolicy::reference reference;
typedef typename AllocationPolicy::const_reference const_reference;
typedef typename AllocationPolicy::value_type value_type;
public :
template <typename U>
struct rebind {
typedef Allocator <U, typename AllocationPolicy::rebind <U> ::other> other;
};
public :
inline explicit Allocator() {}
inline ~Allocator() {}
inline Allocator(Allocator const& rhs):Traits(rhs), Policy(rhs) {}
template <typename U>
inline explicit Allocator(Allocator <U> const&) {}
template <typename U, typename P, typename T2>
inline Allocator(Allocator <U, P, T2> const& rhs):Traits(rhs), Policy(rhs) {}
// memory allocation
// 这里allocate、deallocate是不是重复了,可以删除吗?
inline pointer allocate(size_type cnt, typename std::allocator <void> ::const_pointer hint = 0) {
return AllocationPolicy::allocate(cnt, hint);
}
inline void deallocate(pointer p, size_type cnt) {
AllocationPolicy::deallocate(p, cnt);
}
}; // end of class Allocator
------解决方案--------------------
模板在编译的时候,名字搜索规则是很复杂的。
前面的type重复,是为了避免误用外部空间里的类型定义。
后面一个去掉则问题不大。
有很多语法细节/编程风格的问题,不要钻得太深入。
------解决方案--------------------
在一个模板中为一些类型参数起别名(typedef)已经是C++的习惯了。有什么用呢?看下面的代码:
//一个范型算法,通过交换两个容器的元素
template <class C1, class C2>
exch(C1& cnt1, C2& cnt2) {
??? temp; //这里该用什么类型声明呢?
??? begin1, end1;//还有这里?
??? begin2; //以及这里?
for(; begin1!=end1; ++begin1, ++begin2)
{
temp=*begin1;
*begin1=*begin2;
*begin2=temp;
}
}
由于在编写这个函数模板时我们不知道容器中元素的类型,以及容器的类型,那么,temp的类型也就无从确定了。但是,由于在容器中都声明了一些辅助类型,所以,我们的范型算法才得以实现:
template <class C1, class C2>
exch(C1& cnt1, C2& cnt2) {
C1::value_type temp; //容器通过类型别名给出了容器元素的类型
C1::iterator begin1, end1;//容器通过类型别名给出了迭代器的类型
C2::iterator begin2; // 同上
...
}
从上面的例子中,可以看出,类型别名typedef在范型编程中起到非常重要的作用,尽管他们乍看是没有必要的。推广到一般的模板组件,typedef将模板的使用者同模板的具体实现,在类型上隔离了。用户只需关心模板中某个类型的逻辑含义,而无需关心实际类型。此时,模板便可以对类型进行充分地泛化。
实际上这些typedef是模板接口的一部分。通过这种手段,可以使代码充分泛化,达到最高效编程的目的。
// Policy driven allocator object
template <typename T, typename Policy = StandardAllocPolicy <T> , typename Traits = ObjectTraits <T> >
class Allocator : public Policy, public Traits {
private :
typedef Policy AllocationPolicy;
typedef Traits TTraits;
public : // 这里的重定义是必要的吗?
typedef typename AllocationPolicy::size_type size_type;
typedef typename AllocationPolicy::difference_type difference_type;
typedef typename AllocationPolicy::pointer pointer;
typedef typename AllocationPolicy::const_pointer const_pointer;
typedef typename AllocationPolicy::reference reference;
typedef typename AllocationPolicy::const_reference const_reference;
typedef typename AllocationPolicy::value_type value_type;
public :
template <typename U>
struct rebind {
typedef Allocator <U, typename AllocationPolicy::rebind <U> ::other> other;
};
public :
inline explicit Allocator() {}
inline ~Allocator() {}
inline Allocator(Allocator const& rhs):Traits(rhs), Policy(rhs) {}
template <typename U>
inline explicit Allocator(Allocator <U> const&) {}
template <typename U, typename P, typename T2>
inline Allocator(Allocator <U, P, T2> const& rhs):Traits(rhs), Policy(rhs) {}
// memory allocation
// 这里allocate、deallocate是不是重复了,可以删除吗?
inline pointer allocate(size_type cnt, typename std::allocator <void> ::const_pointer hint = 0) {
return AllocationPolicy::allocate(cnt, hint);
}
inline void deallocate(pointer p, size_type cnt) {
AllocationPolicy::deallocate(p, cnt);
}
}; // end of class Allocator
------解决方案--------------------
模板在编译的时候,名字搜索规则是很复杂的。
前面的type重复,是为了避免误用外部空间里的类型定义。
后面一个去掉则问题不大。
有很多语法细节/编程风格的问题,不要钻得太深入。
------解决方案--------------------
在一个模板中为一些类型参数起别名(typedef)已经是C++的习惯了。有什么用呢?看下面的代码:
//一个范型算法,通过交换两个容器的元素
template <class C1, class C2>
exch(C1& cnt1, C2& cnt2) {
??? temp; //这里该用什么类型声明呢?
??? begin1, end1;//还有这里?
??? begin2; //以及这里?
for(; begin1!=end1; ++begin1, ++begin2)
{
temp=*begin1;
*begin1=*begin2;
*begin2=temp;
}
}
由于在编写这个函数模板时我们不知道容器中元素的类型,以及容器的类型,那么,temp的类型也就无从确定了。但是,由于在容器中都声明了一些辅助类型,所以,我们的范型算法才得以实现:
template <class C1, class C2>
exch(C1& cnt1, C2& cnt2) {
C1::value_type temp; //容器通过类型别名给出了容器元素的类型
C1::iterator begin1, end1;//容器通过类型别名给出了迭代器的类型
C2::iterator begin2; // 同上
...
}
从上面的例子中,可以看出,类型别名typedef在范型编程中起到非常重要的作用,尽管他们乍看是没有必要的。推广到一般的模板组件,typedef将模板的使用者同模板的具体实现,在类型上隔离了。用户只需关心模板中某个类型的逻辑含义,而无需关心实际类型。此时,模板便可以对类型进行充分地泛化。
实际上这些typedef是模板接口的一部分。通过这种手段,可以使代码充分泛化,达到最高效编程的目的。