stl源码剖析学习笔记(二)traits编程技法简明例程

解释说明

traits侯捷老师的翻译是萃取。其目的就是在编译期进行模板调用的类型识别,从而做一些事情。

最突出的例子,我觉得不是《STL源码剖析》中“迭代器概念与traits编程技法"这一章的说明,而是stl算法中copy的实现。代码在stl源码的stl_algobase.h中。

copy的最终实现,大致分为两类,一类是直接整块内存的memmove操作,另一类是一个个对象赋值。其中涉及has_trivial_assignment_operator的类型推断。

如果has_trivial_assignment_operator是__true_type,则进行memmove操作拷贝;如果不是,则一个个对象拷贝。

而基础类型均在type_traits.h中设置有typedef __true_type    has_trivial_assignment_operator;

【注】:所有的类型推导,都是在编译期完成的!!

本篇暂时忽略T、T*、const T*类型偏特化(Partial Specilization)的讨论。

摘抄部分代码如下:
// type_traits.h
__STL_TEMPLATE_NULL struct __type_traits<bool> {
   typedef __true_type    has_trivial_default_constructor;
   typedef __true_type    has_trivial_copy_constructor;
   typedef __true_type    has_trivial_assignment_operator;
   typedef __true_type    has_trivial_destructor;
   typedef __true_type    is_POD_type;
};

// stl_algobase.h

// trivial(平凡的)类型,直接拷贝
template <class _Tp>
inline _Tp*
__copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) {
  memmove(__result, __first, sizeof(_Tp) * (__last - __first));
  return __result + (__last - __first);
}

// 复杂类型,一个个赋值
template <class _InputIter, class _OutputIter, class _Distance>
inline _OutputIter __copy(_InputIter __first, _InputIter __last,
                          _OutputIter __result,
                          input_iterator_tag, _Distance*)
{
  for ( ; __first != __last; ++__result, ++__first)
    *__result = *__first;
  return __result;
}

// 通过判断has_trivial_assignment_operator是否是__true_type决定调用方式
template <class _InputIter, class _OutputIter, class _Tp>
inline _OutputIter __copy_aux(_InputIter __first, _InputIter __last,
                              _OutputIter __result, _Tp*) {
  typedef typename __type_traits<_Tp>::has_trivial_assignment_operator
          _Trivial;
  return __copy_aux2(__first, __last, __result, _Trivial());
}

// __false_type ,使用__copy一个个拷贝
template <class _InputIter, class _OutputIter>
inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last,
                               _OutputIter __result, __false_type) {
  return __copy(__first, __last, __result,
                __ITERATOR_CATEGORY(__first),
                __DISTANCE_TYPE(__first));
}

// __true_type,使用__copy_trivial
template <class _Tp>
inline _Tp* __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result,
                        __true_type) {
  return __copy_trivial(__first, __last, __result);
}
时间: 2024-10-12 14:58:42

stl源码剖析学习笔记(二)traits编程技法简明例程的相关文章

c++ stl源码剖析学习笔记(二)iterator auto_ptr(老版本书籍示例 新版本C++中已经废除此概念)

ITERATOR template<class InputIterator,class T> InputIterator find(InputIterator first,InputIterator last,const T& value) { while(first != last && *first != value) ++first; return first; } 代码示例 1 #include <iostream> 2 #include <v

c++ stl源码剖析学习笔记(一)

template <class InputIterator, class ForwardIterator>inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,ForwardIterator result) 函数使用示例 #include <algorithm> #include <iostream> #include <memory> #inclu

STL 源码剖析读书笔记二:迭代器与traits

1. 迭代器概述 迭代器是一种抽象的设计概念,现实程序语言中并没有直接对应这个概念的实物.<设计模式>中对于迭代器模式的定义为:提供一种方法,使之能够依序访问某个聚合物所含的各个元素,而又无需暴露该聚合物的内部表述方式. STL 的中心思想在于:将数据容器和算法分开,彼此独立设计,再以迭代器粘合.容器和算法的泛型化在技术角度来看并不困难,C++ 的类模板和函数模板可分别达成目标.如何设计出两者的良好粘合剂,才是大难题. 迭代器是一种类似于指针的对象,而指针的各种行为中最常见也最重要的便是内容提

STL源码剖析 学习笔记

目录: 第二章 空间适配器 第三章 迭代器 第四章 序列式容器(vector,list,deque,stack,heap,priority_queue,slist) 第五章 关联式容器(树的算法 + RB_tree ,set,map,hashtable) 第六章 算法 第七章 仿函数 第八章 适配器(adapet) 第二章 空间适配器 具有次配置力的SGI空间适配器,STL allocator将对象的内存分配和初始化分离开,内存配置由alloc:allocate 负责,内存释放由dealloca

重温《STL源码剖析》笔记 第三章

第三章:迭代器概念与traits编程技法 迭代器是一种smart pointer auto_Ptr 是一个用来包装原生指针(native pointer)的对象,声明狼藉的内存泄漏问题可藉此获得解决. auto_ptr用法如下,和原生指针一模一样: void func() { auto_ptr<string> ps(new string("jjhou")); cout << *ps << endl; //输出:jjhou cout <<

重温《STL源码剖析》笔记 第一章

源码之前,了无秘密. --侯杰 经典的书,确实每看一遍都能重新收获一遍: 第一章:STL简介 STL的设计思维:对象的耦合性极低,复用性极高,符合开发封闭原则的程序库. STL的价值:1.带给我们一套极具实用价值的零部件,以及一个整合的组织. 2.带给我们一个高层次的以泛型思维为基础的.系统化的.条理分明的“软件组件分类学”. 在STL接口之下,任何组件都有最大的独立性,并以所谓迭代器胶合起来,或以配接器互相配接,或以所 谓仿函数动态选择某种策略. STL六大组件:1.容器(containers

重温《STL源码剖析》笔记 第四章

源码之前,了无秘密  ——侯杰 第四章:序列式容器 C++语言本身提供了一个序列式容器array array:分配静态空间,一旦配置了就不能改变. vector: 分配动态空间.维护一个连续线性空间,迭代器类型为:Random Access Iterators 空间配置 typedef simple_alloc<value_type, Alloc> data_allocator 所谓动态增加空间大小,并不是在原空间之后接续新空间,而是以原大小的两倍另外配置一块较大 的空间,然后将原内容拷贝过来

STL 源码剖析读书笔记一:空间配置器

1. STL 的空间配置器 STL 空间配置器在运用的角度来说,是最不需要介绍的,它总是隐藏在一切组件背后.但若以 STL 的实现角度而言,第一个需要理解的就是空间配置器. 根据 STL 规范,以下是 allocator 的必要接口: allocator::value_type allocator::pointer allocator::const_pointer allocator::reference allocator::const_reference allocator::size_ty

Stl源码剖析读书笔记之Alloc细节

阅读基础: Foo *pf = new Foo; 执行了两个步骤: 1)::operator new 向系统申请内存. 2) 调用Foo::Foo()构造函数构造实例.  ==> 申请内存,构造实例. delete pf; delete; 执行了两个步骤: 1)调用Foo::~Foo()析构函数. 2). ::operator delete释放内存.         ==> 析构实例,释放内存. Stl Alloc实现: Stl为了高效利用内存,将这两部分分开,分成了四个操作( 构造::con