template<class Arg, class Result> struct unary_function { typedef Arg argument_type; typedef Result result_type; }; template<class Argl, class Arg2, class Result> struct binary_function { typedef Argl first_argument_type; typedef Arg2 second_argument_type; typedef Result result_type; / };
//容器配接器 //stack与queue都是deque的配接器 template<class T,class Sequence=deque<T>> class stack{ ... protected: Sequence c; }; //queue同理,他们只使修饰dequ的接口 //仿函数适配器(not1,not2,bind1st,bind2st,compose1,compose2,ptr_fun,mem_fun,mem_fun_ref) //对返回值进行否定的not1,not2,源代码如下: template<class Predicate> class unary_function:public unary_function<typename Predicate::argument_type,bool>{ protected:pred; //维护一个内部成员,记录仿函数的原始操作 public: explicit unary_negate(const Predicate&x):pred(x){} bool operator()(const typename Predicate::argument_type&x)const{ return !pred(x);//将pred的运算加上否定 } }; //创建辅助函数,使我们能够使用unary_negate<Pred> template<class Predicate> inline unary_negate<Predicate>not1(const Predicate&pred){ return unary_negate<Predicate>(pred); } //class unary_function:public unary_function<typename Predicate::argument_type,bool>这个操作是为了使仿函数增强,可以在配接其他配置器,例如: cout << count_if(vi.begin(),vi.end (), not1(bind2nd(less<int>(), 40))); //对参数进行绑定:bind1st,bind2st template<class Operation> class binderlst:public unary_function<typename Operation::second_argument_type,typename Operation::result_type>{ 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::first_argument_type&x)const{ return op(value,x);//调用表达式,将value绑定为第一参数,我们传入的为第二参数 } }; //辅助函数 template<class Operation,class T> inline binder1st<Operation>bind1st(const Operation,const T&x){ typedef typename Operation::first_argument_type arg1_type; return binder1st<Operation>(op,arg1_type(x)); } //用于函数合成的compose1,compose2 template<class Operation1,class operation2> class unary_compose:public unary_function<typename Operation2::argument_type,typename Oeration1::result_type>{ protected: Operation op1; Operation op2; public: unary_compose(const Operation1&x,conxt Operation2&y):op1(x),op2(y){} typename Operation1::resule_type operator()(const typename Operation2::argument_type&x)const{ return op1(op2(x)); } }; template<class Operation1,class Operation2> inline unary_compose<Operation1,Operation2> compose1(const Operation1& op1,const Operation2& op2){ return unary_compose<Operation2,Operation2>(op1,op2); } //用于函数指针的配接器可以将函数转化为仿函数 //用于成员函数的配接器可以将成员函数转化为仿函数 for_each(v.begon(),v.end(),mem_fun(&Shape::display)); //迭代器配接器:当客户端对insert iterators做复制操作的时候,在inserter iterators中转化为了插入操作// 适配器 template<class Container> class insert_iterator { protected: // 内部成员,记录底层容器和迭代器 Container *container; typename Container::iterator iter; public: // 定义5个关联类型 typedef output_iterator_tag iterator_category; 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永远随其target同步移动 return *this; } // 重载运算符*和++: 不做任何动作 insert_iterator<Container> &operator*() { return *this; } insert_iterator<Container> &operator++() { return *this; } insert_iterator<Container> &operator++(int) { return *this; } }; // 辅助函数inserter template<class Container, class Iterator> inline insert_iterator<Container> inserter(Container &x, Iterator i) { typedef typename Container::iterator iter; return insert_iterator<Container>(x, iter(i)); } //反转迭代器 template<class Iterator> class reverse_iterator { protected: Iterator current; // 对应的正向迭代器 public: // 逆向迭代器的5种关联类型与正向迭代器相同 typedef typename iterator_traits<Iterator>::itrator_category iterator_category; typedef typename iterator_traits<Iterator>::value_type value_type; // ... typedef Iterator iterator_type; // 正向迭代器类型 typedef reverse_iterator<Iterator> self; // 逆向迭代器类型 public: explicit reverse_iterator(iterator_type x) : current(x) {} reverse_iterator(const self &x) : current(x.current) {} iterator_type base() const { return current; } // 逆向迭代器取值: 就是将迭代器视为正向迭代器,退一格再取值 reference operator*() const { Iterator tmp = current; return *--tmp; } pointer operator->() const { return &(operator*()); } // 逆向迭代器的加运算对应正向迭代器的减运算 self &operator++() { --current;return *this; } self &operator--() { ++current;return *this; } self operator+(difference_type n) const { return self(current - n); } self operator-(difference_type n) const { return self(current + n); } }; //流迭代器 std::istream_iterator<double> eos; // 标志迭代器,通过与该迭代其比较以判断输入流是否终止 std::istream_iterator<double> iit(std::cin); // 封装std::cin的输入流迭代器 double value; if (iit != eos) value = *iit; // 从输入流读取数据到变量value中,相当于: std::cin >> cvalue template<class T, class charT=char, class traits=char_traits<charT>, class Distance=ptrdiff_t> class istream_iterator : public iterator<input_iterator_tag, T, Distance, const T *, const T &> { basic_istream<charT, traits> *in_stream; // 输入流 T value; // 上一次读入的值 public: typedef charT char_type; typedef traits traits_type; typedef basic_istream<charT, traits> istream_type; istream_iterator() : in_stream(0) {} // 空迭代器,表示输入流终止 istream_iterator(istream_type &s) : in_stream(&s) { ++*this; } // 创建好迭代器后马上读入一个值 istream iterator(const istream_iterator<T, charT, traits, Distance> &x) : in_stream(x.in_stream), value(x.value) {} // 重载运算符++ istream_iterator<T, charT, traits, Distance> &operator++() { if (in_stream && !(*in_stream >> value)) in_stream = 0; return *this; } istream_iterator<T, charT, traits, Distance> operator++(int) { istream_iterator<T, charT, traits, Distance> tmp = *this; ++*this; return tmp; } // 重载运算符*和-> const T &operator*() const { return value; } const T *operator->() const { return &value; } };
代码参考(https://blog.csdn.net/ncepu_Chen/article/details/114947710)
书籍参考:stl源码剖析
c++系列文章:
【c++从菜鸡到王者】第八篇:深度剖析Traits技法
【c++从菜鸡到王者】第七篇:STL-空间配置器
【c++从菜鸡到王者】第六篇:详解晦涩难懂的c++语法
【c++从菜鸡到王者】第五篇-( 全网最精华)条件编译ifdef的用法
【c++从菜鸡到王者】第4篇:STL非标准容器-hashtable
【c++从菜鸡到王者】第三篇:STL关联容器-Map
【c++从菜鸡到王者】第二篇:STL关联容器-(multi)Set
【c++从菜鸡到王者】第一篇:STL之主要序列容器
如何使用好STL?这些经验你必须知道(进阶必备,建议收藏)!