读书人

《stl源码剖解》 析构函数destroy分析

发布时间: 2013-01-05 15:20:39 作者: rapoo

《stl源码剖析》 析构函数destroy分析
《stl源码剖析》 p51


//判断元素的数值型别,使用trivial destructor
template<class ForwardIterator,class T>
inline void __destroy(ForwardIterator first,ForwardIterator last,T*)
{
typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;
__destroy_aux(first,last,trivial_destructor());
}

//如果元素的数值型别(value type) 有non-trival destructor
template<class ForwardIterator>
inline void __destory_aux(ForwardIterator first,ForwardIterator last,false_type)
{
for(;first<last;++first)
destroy(&first);
}
//如果元素的数值型别(value type)有trivial destructor
template<class ForwardIterator>
inline void __destroy_aux(ForwardIterator,ForwardIterator,true_type){}

我不理解的地方在
1,typedef typename
typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;

如果代码是如下,我能理解些,trivial_destructor 就是 has_trivial_destructor,但是其中有个 typename
typedef __type_traits<T>::has_trivial_destructor trivial_destructor;


2,__type_traits<T>
__type_traits<T>在vc2010中定位不到,这个__type_traits<T>是命名空间还是静态类?

3,has_trivial_destructor
在vc2010中定位过去的话,如下代码,这个是个struct,而代码trivial_destructor()应该是调用了struct中的operator() 方法

// TEMPLATE CLASS has_trivial_destructor
template<class _Ty>
struct has_trivial_destructor _HAS_TRIVIAL_DESTRUCTOR(_Ty)
{// determine whether _Ty has a trivial destructor
};

_HAS_TRIVAL_DESTRUCTOR()定位到如下代码
  #define _HAS_TRIVIAL_DESTRUCTOR(_Ty)\
: _Cat_base<!is_void<_Ty>::value \
&& (is_pod<_Ty>::value || __has_trivial_destructor(_Ty))>

整合起来就是,我没有找到struct中的operator(),反而,struct 还返回值了,很郁闷啊

template<class _Ty>
struct has_trivial_destructor : _Cat_base<!is_void<_Ty>::value && (is_pod<_Ty>::value || __has_trivial_destructor(_Ty))>
{// determine whether _Ty has a trivial destructor
};



4,__destroy_aux(first,last,trivial_destructor());
如果我写这个代码,一定是如下代码

if(trivial_destructor())
{
for(;first<last;++first)
destroy(&first);
}
else
{
}

向stl大牛一样写成2个方法有什么好处呢,易扩展么?
//如果元素的数值型别(value type) 有non-trival destructor
template<class ForwardIterator>
inline void __destory_aux(ForwardIterator first,ForwardIterator last,false_type)
{
for(;first<last;++first)
destroy(&first);
}
//如果元素的数值型别(value type)有trivial destructor
template<class ForwardIterator>
inline void __destroy_aux(ForwardIterator,ForwardIterator,true_type){}



希望csdn上c++大牛能解答下困惑,本人刚开始学习《stl源码剖析》这本书
[解决办法]
1 没有typename的话就编译错误了,这里的typename给编译器看的说明
__type_traits<T>::has_trivial_destructor是一个类型,没有typename的话 那么
__type_traits<T>::has_trivial_destructor就认为是一个静态变量
2 这是sgi版的 stl VS没有 __type_traits 很正常,这是一个模板类
3 这里不需要有operator,需要的一个类型
4 你试试看能编译过去么?
------解决方案--------------------


前面三个问题其实楼主自己应该都可以慢慢找到答案,偶就解释一下第四个问题吧。

不知道楼主听说过元编程没有?这里虽然没有实际使用元编程的方法,但运用了元编程的技巧,它利用重载解析把条件选择由运行期转移到了编译期,那个false_type和true_type就是用来这个用途的,由于在__destory_aux函数体内没有使用形参名称,因此false_type和true_type的形参变量名可以忽略。

如果换成了你的代码,条件选择就会产生实体代码,性能必然受到影响。不仅如此,无论条件选择的结果如何,两种结果的实体代码都会产生,这增大了程序的体积,对于STL这种重要的标准库来说,这种性能和体积损失都是不可接受的。

而STL使用的元编程方法,编译期就已经知道将产生哪一种结果的代码了,编译后就只产生这部分代码。

此外,__type_traits是一个一阶元函数,以一种非侵入的方式提供各种属性服务,has_trivial_destructor就是这个元函数的其中一个结果。

不过,STL的traits通常是一堆大杂烩,被MPL的作者讥讽为一种反模式的blob,呵呵。

读书人网 >C++

热点推荐