【STL源码剖析】__type_traits技法
2016-06-04 14:53
561 查看
上篇介绍了__iterator_traits编程技法,SGI 将这种技法进一步扩大到迭代器以外,于是有了所谓的__type_traits。
iterator_traits负责萃取迭代器的特性,__type_traits则负责萃取型别的特性。
而这里我们关注的型别特性是指:这个型别是否具备non-trivial default ctor\non-trivial copy ctor\ non-trivial assignment\non-trivial dtor?根据型别我们就可以进行构造、析构、拷贝、赋值最有效率的措施,例如根本不调用那些身居高位、不谋其事的那些ctor、dtor,而采用内存直接处理操作如malloc()、memcpy()等等,获得最高效率,在大规模而操作频繁的容器有着显著的效率提升。
关于怎样是trivial(没用的)\non-trivial(有用的),可以看《深入探索C++对象模型》。
SGI STL内部有定义:
template<class type>
struct __type_traits
{
typedef __true_type this_dummy_member_must_be_first;
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
struct __false_type{};
struct __true_type{};
还有一些对内置类型的特例化版本,上面是保守的定义,设计了自己的类后,要特例化自己的版本:
class MyClass
{};
template<>
struct __type_traits<MyClass>
{
typedef __true_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
通过__false_type/__true_type来判别是否具备有用的构造、析构、赋值、复制函数。
那么,SGI STL是如何在算法中应用的呢?看下面,以算法函数uninitialized_fill_n为例:
template<class ForwardIterator, class Size, class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x)
{
return __uninitialized_fill_n(first, n, x, value_type(first));
}
template<class ForwardIterator, class Size, class T, class T1>
inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n, const T& x, T1*)
{
typedef typename __type_traits<T1>::is_POD_type is_POD;
return __uninitialized_fill_n(first, n, x, is_POD());
}
template<class ForwardIterator, class Size, class T>
inline ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first, Size n, const T& x, __false_type)
{
for (;n > 0; --n,++cur)
construct(&*cur, x);
return cur;
}
template<class ForwardIterator, class Size, class T>
inline ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first, Size n, const T& x, __true_type)
{
return fill_n(first, n, x);
}
template<class OutputIterator, class Size, class T>
OutputIterator fill_n(OuputIterator first, Size n, const T& value)
{
for (;n > 0;--n)
*first = value;
return first;
}
value_type是萃取元素类型的函数,也是模板实现,
construct底层高效率调用,不是使用构造函数
上面就是__type_traits了。
iterator_traits负责萃取迭代器的特性,__type_traits则负责萃取型别的特性。
而这里我们关注的型别特性是指:这个型别是否具备non-trivial default ctor\non-trivial copy ctor\ non-trivial assignment\non-trivial dtor?根据型别我们就可以进行构造、析构、拷贝、赋值最有效率的措施,例如根本不调用那些身居高位、不谋其事的那些ctor、dtor,而采用内存直接处理操作如malloc()、memcpy()等等,获得最高效率,在大规模而操作频繁的容器有着显著的效率提升。
关于怎样是trivial(没用的)\non-trivial(有用的),可以看《深入探索C++对象模型》。
SGI STL内部有定义:
template<class type>
struct __type_traits
{
typedef __true_type this_dummy_member_must_be_first;
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
struct __false_type{};
struct __true_type{};
还有一些对内置类型的特例化版本,上面是保守的定义,设计了自己的类后,要特例化自己的版本:
class MyClass
{};
template<>
struct __type_traits<MyClass>
{
typedef __true_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
通过__false_type/__true_type来判别是否具备有用的构造、析构、赋值、复制函数。
那么,SGI STL是如何在算法中应用的呢?看下面,以算法函数uninitialized_fill_n为例:
template<class ForwardIterator, class Size, class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x)
{
return __uninitialized_fill_n(first, n, x, value_type(first));
}
template<class ForwardIterator, class Size, class T, class T1>
inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n, const T& x, T1*)
{
typedef typename __type_traits<T1>::is_POD_type is_POD;
return __uninitialized_fill_n(first, n, x, is_POD());
}
template<class ForwardIterator, class Size, class T>
inline ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first, Size n, const T& x, __false_type)
{
for (;n > 0; --n,++cur)
construct(&*cur, x);
return cur;
}
template<class ForwardIterator, class Size, class T>
inline ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first, Size n, const T& x, __true_type)
{
return fill_n(first, n, x);
}
template<class OutputIterator, class Size, class T>
OutputIterator fill_n(OuputIterator first, Size n, const T& value)
{
for (;n > 0;--n)
*first = value;
return first;
}
value_type是萃取元素类型的函数,也是模板实现,
construct底层高效率调用,不是使用构造函数
上面就是__type_traits了。
相关文章推荐
- 从源码安装Mysql/Percona 5.5
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- Lua和C语言的交互详解
- 浅析Ruby的源代码布局及其编程风格
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- C语言练习题:自由落体的小球简单实例
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- C语言中进制知识汇总
- C语言中计算正弦的相关函数总结
- 使用C语言详解霍夫曼树数据结构