STL学习_配接器篇
定义
配接器(Adapter)在STL组件的灵活组合运用功能上,扮演着轴承、转换器的角色。它事实上是一种设计模式。即将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes,可以一起运作。
分类
STL所提供的各种适配器中,改变仿函数(functors)接口者,称为function adapter;改变容器(containers)接口者,称为container adapter;改变迭代器(iterators)接口者,称为iterator adapter。
functor adapters
functor adapters是所有配接器中数量最庞大的一个族群,其配接灵活度是后两者不能及的,可以配接、配接、在配接。其中配接操作包括系结(bind)、否定(negate)、组合(compose)、以及对一般函数或成员函数的修饰(使其成为一个仿函数)。它的价值在于,通过它们之间的绑定、组合、修饰能力,几乎可以无限制地创造出各种可能的表达式(expression),搭配STL算法一起演出。
由于仿函数就是“将function call操作符重载”的一种class,而任何算法接受一个仿函数时,总是在其演算过程中调用该仿函数的operator(),这使得不具备仿函数之形、却有真函数之实的“一般函数”和“成员函数(member functions)感到为难。如果”一般函数“和“成员函数”不能纳入复用的体系中,则STL的规划将崩落了一角。为此,STL提供了为数众多的配接器,使“一般函数”和“成员函数”得以无缝地与其他配接器或算法结合起来。
注意,所有期望获取配接能力的组件,本身都必须是可配接的,即一元仿函数必须继承自unary_function,二元仿函数必须继承自binary_function,成员函数必须以mem_fun处理过,一般函数必须以ptr_fun处理过。一个未经ptr_fun处理过的一般函数,虽然也可以函数指针的形式传给STL算法使用,却无法拥有任何配接能力。
container adapters
STL提供了两个容器queue和stack,其实都只不过是一种配接器。它们修饰deque的接口而成就出另一种风貌。queue和stack底层都是由deque构成的,它们封住所有deque对外接口,只开发符合对应原则的几个函数,故它们是适配器,是一个作用于容器之上的适配器。
iterator adapters
STL提供了许多应用于迭代器身上的配接器,包括insert iterators,reverse iterators,iostream iterators。insert iterators可以将一般迭代器的赋值(assign)操作转变为插入(insert)操作。此迭代器包括专门从尾端插入操作back_insert_iterator,专门从头端插入操作front_insert_iterator,以及可从任何位置执行插入操作的insert_iterator。因iterator adapters使用接口不是十分直观,STL提供三个相应的函数back_inserter()、front_inserter()、inserter(),从而提高使用时的便利性。reverse iterators可以将一般迭代器的行进方向逆转,使原本应该前进的operator++变成了后退操作,使原本应该后退的operator–变成了前进操作。此操作用在“从尾端开始进行”的算法上,有很大的方便性。iostream\ iterators可以将迭代器绑定到某个iostream对象身上。绑定到istream对象身上,为istream_iterator,拥有输入功能;绑定到ostream对象身上,成为ostream_iterator,拥有输出功能。此迭代器用在屏幕输出上,非常方便。
源码分析
1)insert iterator
// iterator adapter迭代器配接器,用来将某个迭代器的赋值(assign)操作 // 修改为插入(insert)操作——从容器的尾端插入进去,故称为back_insert template class back_insert_iterator { protected: _Container* container; // 底部容器 public: typedef _Container container_type; // 注意类型 typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; // 使用back_insert_iterator与容器绑定起来 explicit back_insert_iterator(_Container& __x) : container(&__x) {} back_insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->push_back(__value); // 关键,转而调用push_back() return *this; } // 以下三个操作符对back_insert_iterator不起作用(关闭功能) // 三个操作符返回的都是back_insert_iterator自己 back_insert_iterator<_Container>& operator*() { return *this; } back_insert_iterator<_Container>& operator++() { return *this; } back_insert_iterator<_Container>& operator++(int) { return *this; } }; // 辅助函数,便于使用back_insert_iterator template inline back_insert_iterator<_Container> back_inserter(_Container& __x) { return back_insert_iterator<_Container>(__x); // 这是一个迭代器配接器(iterator adapter),用来将某个迭代器的赋值(assign)操作修改为插入(insert) // 操作——从容器的头端插入进去(称为front_insert) // 注意,该迭代器不适用于vector,因为vector都没提供push_front函数 template class front_insert_iterator { protected: _Container* container; // 底层容器 public: typedef _Container container_type; // 注意类型 typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit front_insert_iterator(_Container& __x) : container(&__x) {} front_insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->push_front(__value); // 此处为关键,转而调用push_front() return *this; } // 以下三个操作符对front_insert_iterator不起作用(关闭功能) // 三个操作符返回的都是front_insert_iterator自己 front_insert_iterator<_Container>& operator*() { return *this; } front_insert_iterator<_Container>& operator++() { return *this; } front_insert_iterator<_Container>& operator++(int) { return *this; } }; // 辅助函数,便于使用front_insert_iterator template inline front_insert_iterator<_Container> front_inserter(_Container& __x) { return front_insert_iterator<_Container>(__x); } // 这是一个迭代器适配器(iterator adapter),用来将某个迭代器的赋值assign操作修改为插入(insert) // 操作,在指定的位置上进行,并将迭代器右移一个位置——如此便可很方便地连续执行“表面上是赋值(覆写) // 而实际上是插入”的操作。 template class insert_iterator { protected: _Container* container; // 底层容器 typename _Container::iterator iter; public: typedef _Container container_type; // 注意类型 typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x, typename _Container::iterator __i) : container(&__x), iter(__i) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { iter = container->insert(iter, __value); // 此处为关键,转调用insert()函数 ++iter; // 注意此处,使insert_iterator永远随其目标贴身移动 return *this; } // 以下三个操作符对insert_iterator不起作用(关闭功能) // 三个操作符返回的都是insert_iterator自己 insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; // 辅助函数,便于使用insert_iterator template inline insert_iterator<_Container> inserter(_Container& __x, _Iterator __i) { typedef typename _Container::iterator __iter; return insert_iterator<_Container>(__x, __iter(__i)); }
2)reverse iterator
// 迭代器配接器(iterator adapter),用来将某个迭代器逆反前进方向,使前进为后退,后退为前进 class reverse_iterator { typedef reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance> _Self; // 代表逆向迭代器 protected: _RandomAccessIterator current; // 记录对应之正向迭代器 public: // 逆向迭代器的5种相应型别(associated types)都和其对应的正向迭代器相同 typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Reference reference; reverse_iterator() {} // 将reverse_iterator与某个迭代器x系结起来 explicit reverse_iterator(_RandomAccessIterator __x) : current(__x) {} _RandomAccessIterator base() const { return current; } // 取出对应的正向迭代器 _Reference operator*() const { return *(current - 1); } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ // 前进(++)变成后退(--) _Self& operator++() { --current; return *this; } _Self operator++(int) { _Self __tmp = *this; --current; return __tmp; } // 后退(--)变成前进(++) _Self& operator--() { ++current; return *this; } _Self operator--(int) { _Self __tmp = *this; ++current; return __tmp; } // 前进与后退完全逆转 _Self operator+(_Distance __n) const { return _Self(current - __n); } _Self& operator+=(_Distance __n) { current -= __n; return *this; } _Self operator-(_Distance __n) const { return _Self(current + __n); } _Self& operator-=(_Distance __n) { current += __n; return *this; } // 注意:下面第一个*和唯一一个+都会调用本类的operator*和operator+ // 第二个*则不会(判断法则:完全看处理的型别而定) _Reference operator[](_Distance __n) const { return *(*this + __n); } };
3)stream iterators
// input iterator,能够为“来自某一basic_istream”的对象执行格式化输入操作 template class istream_iterator { #ifdef __STL_TEMPLATE_FRIENDS template friend bool operator==(const istream_iterator<_T1, _D1>&, const istream_iterator<_T1, _D1>&); #else /* __STL_TEMPLATE_FRIENDS */ friend bool __STD_QUALIFIER operator== __STL_NULL_TMPL_ARGS (const istream_iterator&, const istream_iterator&); #endif /* __STL_TEMPLATE_FRIENDS */ protected: istream* _M_stream; _Tp _M_value; bool _M_end_marker; void _M_read() { _M_end_marker = (*_M_stream) ? true : false; if (_M_end_marker) *_M_stream >> _M_value; // 关键 // 以上,输入之后,stream的状态可变,所以下面再判断一次以决定end_marker // 当读到eof或读到型别不符的资料,stream即处于false状态 _M_end_marker = (*_M_stream) ? true : false; } public: typedef input_iterator_tag iterator_category; typedef _Tp value_type; typedef _Dist difference_type; typedef const _Tp* pointer; typedef const _Tp& reference; // 以上,因身为input iterator,所以采用const比较保险 istream_iterator() : _M_stream(&cin), _M_end_marker(false) {} istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); } reference operator*() const { return _M_value; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ // 迭代器前进一个位置,就代表要读取一批数据 istream_iterator<_Tp, _Dist>& operator++() { _M_read(); return *this; } istream_iterator<_Tp, _Dist> operator++(int) { istream_iterator<_Tp, _Dist> __tmp = *this; _M_read(); return __tmp; } }; // output iterator,能够将对象格式化输出到某个basic_ostream上 template class ostream_iterator { protected: ostream* _M_stream; const char* _M_string; // 每次输出后的间隔符号,变量名称为string public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {} ostream_iterator(ostream& __s, const char* __c) : _M_stream(&__s), _M_string(__c) {} // 对迭代器做赋值(assign)操作,就代表要输出一批数据 ostream_iterator<_Tp>& operator=(const _Tp& __value) { *_M_stream << __value; // 关键:输出数值 if (_M_string) *_M_stream << _M_string; // 如果间隔符号不为空,输出间隔符号 return *this; } // 注意以下三个操作 ostream_iterator<_Tp>& operator*() { return *this; } ostream_iterator<_Tp>& operator++() { return *this; } ostream_iterator<_Tp>& operator++(int) { return *this; } };
4)function adapters
对返回值进行逻辑否定:not1,not2
// 以下配接器用来表示某个Adaptable Predicate的逻辑负值 template class unary_negate : public unary_function { protected: _Predicate _M_pred; // 内部成员 public: explicit unary_negate(const _Predicate& __x) : _M_pred(__x) {} bool operator()(const typename _Predicate::argument_type& __x) const { return !_M_pred(__x); // 将pred的运算结果加上否定(negate)运算 } }; // 辅助函数,以便于使用unary_negate<_Predicate> template inline unary_negate<_Predicate> not1(const _Predicate& __pred) { return unary_negate<_Predicate>(__pred); } // 以下适配器用来表示某个Adapter Binary Predicate的逻辑负值 template class binary_negate : public binary_function { protected: _Predicate _M_pred; // 内部成员 public: explicit binary_negate(const _Predicate& __x) : _M_pred(__x) {} bool operator()(const typename _Predicate::first_argument_type& __x, const typename _Predicate::second_argument_type& __y) const { return !_M_pred(__x, __y); // 将pred的运算结果加上否定(negate)运算 } }; // 辅助函数,便于使用binary_negate<_Predicate> template inline binary_negate<_Predicate> not2(const _Predicate& __pred) { return binary_negate<_Predicate>(__pred); }
对参数进行绑定:bind1st,bind2nd
// 以下配接器用来将某个Adapter Binary function转换为Unary Function template class binder1st : public unary_function { protected: _Operation op; // 内部成员 typename _Operation::first_argument_type value; // 内部成员 public: binder1st(const _Operation& __x, const typename _Operation::first_argument_type& __y) : op(__x), value(__y) {} // 将表达式和第一参数记录于内部成员 typename _Operation::result_type operator()(const typename _Operation::second_argument_type& __x) const { return op(value, __x); // 实际调用表达式,并将value绑定为第一参数 } }; // 辅助函数,方便应用binder1st<_Operation> template inline binder1st<_Operation> bind1st(const _Operation& __fn, const _Tp& __x) { typedef typename _Operation::first_argument_type _Arg1_type; return binder1st<_Operation>(__fn, _Arg1_type(__x)); } // 以下配接器用来将Adaptable Binary function转换为Unary Function template class binder2nd : public unary_function { protected: _Operation op; // 内部成员 typename _Operation::second_argument_type value; // 内部成员 public: binder2nd(const _Operation& __x, const typename _Operation::second_argument_type& __y) : op(__x), value(__y) {} // 将表达式和第一参数记录于内部成员 typename _Operation::result_type operator()(const typename _Operation::first_argument_type& __x) const { return op(__x, value); // 实际调用表达式,并将value绑定为第二参数 } }; // 辅助函数,便于使用binder2nd<_Operation> template inline binder2nd<_Operation> bind2nd(const _Operation& __fn, const _Tp& __x) { typedef typename _Operation::second_argument_type _Arg2_type; return binder2nd<_Operation>(__fn, _Arg2_type(__x)); }
用于函数合成:compose1,compose2
// 已知两个Adapter Unary Functions f(),g(),以下配接器用来产生一个h(),使得h(x) = f(g(x)) template class unary_compose : public unary_function { protected: _Operation1 _M_fn1; // 内部成员 _Operation2 _M_fn2; // 内部成员 public: unary_compose(const _Operation1& __x, const _Operation2& __y) : _M_fn1(__x), _M_fn2(__y) {} // 将两个表达式记录于内部成员 typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { return _M_fn1(_M_fn2(__x)); // 函数合成 } }; // 辅助函数,让我们得以方便运用unary_compose<_Operation1,_Operation2> template inline unary_compose<_Operation1,_Operation2> compose1(const _Operation1& __fn1, const _Operation2& __fn2) { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); } // 已知一个Adapter Binary Function f和两个Adaptable Unary Functions g1,g2 // 以下配接器用来产生一个h,使h(x) = f(g1(x), g2(x)) template class binary_compose : public unary_function { protected: _Operation1 _M_fn1; // 内部成员 _Operation2 _M_fn2; // 内部成员 _Operation3 _M_fn3; // 内部成员 public: binary_compose(const _Operation1& __x, const _Operation2& __y, const _Operation3& __z) : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); // 函数合成 } }; // 辅助函数,让我们得以方便运用binary_compose<_Operation1,_Operation2,_Operation3> template inline binary_compose<_Operation1, _Operation2, _Operation3> compose2(const _Operation1& __fn1, const _Operation2& __fn2, const _Operation3& __fn3) { return binary_compose<_Operation1,_Operation2,_Operation3> (__fn1, __fn2, __fn3); }
用于函数指针:ptr_fun
// 以下配接器其实就是把一个一元函数指针包起来; // 当仿函数被使用时,就调用该函数指针 template class pointer_to_unary_function : public unary_function<_Arg, _Result> { protected: _Result (*_M_ptr)(_Arg); // 内部成员,一个函数指针 public: pointer_to_unary_function() {} // 以下constructor将函数指针记录于内部成员之中 explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {} // 通过函数指针执行函数 _Result operator()(_Arg __x) const { return _M_ptr(__x); } }; // 辅助函数,使我们能够方便运用pointer_to_unary_function template // pointer_to_unary_function<_Arg, _Result>是函数的返回值 inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg)) { return pointer_to_unary_function<_Arg, _Result>(__x); } // 以下配接器其实就是把一个二元函数指针包起来; // 当仿函数被使用时,就调用该函数指针 template class pointer_to_binary_function : public binary_function<_Arg1,_Arg2,_Result> { protected: _Result (*_M_ptr)(_Arg1, _Arg2); // 内部成员,一个函数指针 public: pointer_to_binary_function() {} // 以下constructor将函数指针记录于内部成员之中 explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) : _M_ptr(__x) {} // 以下,通过函数指针执行函数 _Result operator()(_Arg1 __x, _Arg2 __y) const { return _M_ptr(__x, __y); } }; // 辅助函数,使我们能够方便运用pointer_to_binary_function template // pointer_to_binary_function<_Arg1,_Arg2,_Result>是函数的返回值 inline pointer_to_binary_function<_Arg1,_Arg2,_Result> ptr_fun(_Result (*__x)(_Arg1, _Arg2)) { return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__x); }
用于成员函数指针:mem_fun,men_fun_ref
// 这个族群一共有8 = 2^3个function objects // 1)“无任何参数”vs“有一个参数” // 2)“通过pointer调用”vs“通过refernece调用” // 3)“const成员函数”vs“non-const成员函数” // 所有复杂都只存在于function objects内部。可以忽略它们,直接使用更上层的辅助函数mem_fun和 // mem_fun_ref,它们会产生适当的配接器 // “无任何参数”、“通过pointer调用”、“non-const成员函数” template class mem_fun_t : public unary_function<_Tp*,_Ret> { public: explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} // 记录下来 _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } // 转调用 private: _Ret (_Tp::*_M_f)(); // 内部成员,pointer to member function }; // “无任何参数”、“通过pointer调用”、“const成员函数” template class const_mem_fun_t : public unary_function { public: explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); } private: _Ret (_Tp::*_M_f)() const; // 内部成员,pointer to const member function }; // “无任何参数”、“通过reference调用”、“non-const成员函数” template class mem_fun_ref_t : public unary_function<_Tp,_Ret> { public: explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} // 记录下来 _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); } // 转调用 private: _Ret (_Tp::*_M_f)(); // 内部成员,pointer to member function }; // “无任何参数”、“通过reference调用”、“const成员函数” template class const_mem_fun_ref_t : public unary_function<_Tp,_Ret> { public: explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); } private: _Ret (_Tp::*_M_f)() const; // 内部成员,pointer to const member function }; // “有一个参数”、“通过pointer调用”、“non-const成员函数” template class mem_fun1_t : public binary_function<_Tp*,_Arg,_Ret> { public: explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} // 转录下来 _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } // 转调用 private: _Ret (_Tp::*_M_f)(_Arg); // 内部成员,pointer to member function }; // “有一个参数”、“通过pointer调用”、“const成员函数” template class const_mem_fun1_t : public binary_function { public: explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} _Ret operator()(const _Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } private: _Ret (_Tp::*_M_f)(_Arg) const; // 内部成员,pointer to const member function }; // “有一个参数”、“通过reference调用”、“non-const成员函数” template class mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { public: explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} // 记录下来 _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } // 转调用 private: _Ret (_Tp::*_M_f)(_Arg); // 内部成员,pointer to member function }; // “有一个参数”、“通过reference调用”、“const成员函数” template class const_mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { public: explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } private: _Ret (_Tp::*_M_f)(_Arg) const; // 内部成员,pointer to const member function }; // mem_fun adapter的辅助函数:mem_fun,mem_fun_ref template inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } template inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } // 以下四个函数,其实可以采用和先前(以上)四个函数相同的名称(函数重载) template inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } template inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } template inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } template inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); }