zoukankan      html  css  js  c++  java
  • STL源码剖析:配接器

    • 配接器就是适配器

    • STL中的适配器一共三种:

      • 迭代器适配器

        • 是一种观念上的改变,如将赋值操作变成插入,前进变成后退,等

      • 函数适配器

        • STL中最广泛的配接器群体

        • 可以实现连续配接

        • 配接操作:bind,negate,compose

      • 容器适配器

        • stack和queue的底层都是deque

    Iterator adapter

    • iterator adapter中也维护一个容器,iterator adapter就是开放内部维护的容器的一些方法和关闭一些方法

    • back_insert_iterator:将赋值操作变成尾插

    template <class Container>
    class back_insert_iterator
    {
    protected:
        Container* container;
        
    public:
        explict back_insert_iterator(Container& x) : container(&x) {}
        
        // 主要提供的方法
        back_insert_iterator<Container>& operator=(const typename Container::value_type& value)
        {
            container->push_back(value);
            return *this;
        }
        
        // 关闭下列方法
        back_insert_iterator<Container>& operator*() { return *this; }
        back_insert_iterator<Container>& operator++() { return *this; }
        back_insert_iterator<Container>& operator++(int) { return *this; }
    }
    
    template <class Container>
    inline back_insert_iterator<Container> back_inserter(Container& x)
    {
        return back_insert_iterator<Container>(x);
    }
    •  front_insert_iterator:将赋值操作变成头插
    template <class Container>
    class front_insert_iterator
    {
    protected:
        Container* container;
        
    public:
        explict front_insert_iterator(Container& x) : container(&x) {}
        
        // 主要提供的方法
        front_insert_iterator<Container>& operator=(const typename Container::value_type& value)
        {
            container->push_front(value);
            return *this;
        }
        
        // 关闭下列方法
        front_insert_iterator<Container>& operator*() { return *this; }
        front_insert_iterator<Container>& operator++() { return *this; }
        front_insert_iterator<Container>& operator++(int) { return *this; }
    }
    
    template <class Container>
    inline front_insert_iterator<Container> front_inserter(Container& x)
    {
        return front_insert_iterator<Container>(x);
    }
    • insert_iterator:将赋值操作变成在指定位置后插入,便于连续赋值
    template <class Container>
    class insert_iterator
    {
    protected:
        Container* container;
        typename Container::iterator iter;
        
    public:
        explictinsert_iterator(Container& x, typename Container::iterator i) : container(&x), iter(i) {}
        
        // 主要提供的方法
        insert_iterator<Container>& operator=(const typename Container::value_type& value)
        {
            container->insert(iter, value);
            ++iter;
            return *this;
        }
        
        // 关闭下列方法
        insert_iterator<Container>& operator*() { return *this; }
        insert_iterator<Container>& operator++() { return *this; }
        insert_iterator<Container>& operator++(int) { return *this; }
    }
    
    template <class Container, class Iterator>
    inline insert_iterator<Container> front_inserter(Container& x, Iterator i)
    {
        typedef typename Container::iterator iter;
        return insert_iterator<Container>(x, iter(i));
    }
    • reverse_iterator:将某个迭代器反向移动
    template <class Iterator>
    class reverse_iterator
    {
    protected:
        Iterator current;
        
    public:
        typedef Iterator iterator_type; // 正向迭代器
        typedef reverse_iterator<Iterator> self; // 反向迭代器
        
        reverse_iterator() {}
        explicit reverse_iterator(iterator_type x) : current(x) {}
        explicit reverse_iterator(const self& x) : current(x.current) {}
        
        iterator_type base() const { return currrent; }
        
        reference operator*() const 
        {
            Iterator tmp = current;
            return *--tmp;
        }
        
        reference operator->() const 
        {
            return &(operator*());
        }
        
        self& operator++()
        {
            --current;
            return *this;
        }
        
        self& operator++(int)
        {
            self tmp = current;
            --current;
            return tmp;
        }
        
        self& operator--()
        {
            ++current;
            return *this;
        }
        
        self& operator--(int)
        {
            self tmp = current;
            ++current;
            return tmp;
        }
        
        self operato+(difference_type n) const
        {
            return self(current - n);
        }
        
        self& operato+=(difference_type n)
        {
            current -= n;
            return self;
        }
        
        self operato-(difference_type n) const
        {
            return self(current + n);
        }
        
        self& operato-=(difference_type n)
        {
            current += n;
            return self;
        }
        
        reference operator[](difference_type n) const
        {
            return *(*this + n)
        }
    }
    • istream_iterator:绑定到istream上,拥有输入能力
    template <class T, class Distance = ptrdiff_t>
    class istream_iterator
    {
    protected:
        istream* stream;
        T value;
        bool end_mark;
        void read()
        {
            end_mark = (*stream) ? true :false;
            if(end_mark)
            {
                *stream >> value;    
            }
            end_mark = (*stream) ? true :false;
        }
        
    public:
        istream_iterator() : stream(&cin), end_mark(false) {}
        istream_iterator(istream& s) : stream(&s), end_mark(false) { read(); }
        
        reference operator*() const { return value; }
        reference operator->() const { return &(operator*()); }
        
        istream_iterator<T, Distance>& operator++()
        {
            read();
            return *this;
        }
        
        istream_iterator<T, Distance>& operator++(int)
        {
            istream_iterator<T, Distance> tmp = *this;
            read();
            return tmp;
        }
    }
    • ostream_iterator:绑定到ostream上,拥有输出能力
    template <class T>
    class ostream_iterator
    {
    protected:
        ostream* stream;
        const char* string; // 每次输出后的间隔符
    
    public:
        ostream_iterator(ostream& s) :stream(&s), string(0) {}
        ostream_iterator(ostream& s, const char* c): stream(&s), string(c) {}
        
        ostream_iterator<T>& operator=(const T& value)
        {
            *stream << value;
            if(string)
            {
                *stream << string;
            }
            return *this;
        }
        
        ostream_iterator<T>& operator*() { return *this; }
        ostream_iterator<T>& operator++() { return *this; }
        ostream_iterator<T>& operator++(int) { return *this; }
    }

    Function adapter

    • 就是使用组合的方式,组合多个仿函数

    • 对返回值进行逻辑取反:not1、not2

    // 配接的仿函数接收两个参数
    template <class Predicate>
    class binary_negate : public binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool>
    {
        Predicate pre;
    public:
        explicate binary_negate(const Predicate& x) :prd(x) {}
        
        bool operator()(const typename Predicate::argument_type& x, typename Predicate::second_argument_type& y) const
        {
            return !(ped(x, y));
        }
    }
    
    template <class Predicate>
    inline binary_negate<Predicate> not2(const Predicate& pred)
    {
        return binary_negate<Predicate>(pred);
    }
    • 对参数进行绑定:bind1st、bind2nd
      • 就是指定仿函数中的参数中的某一个为固定值

    template <class Operator>
    class binder1st : public unary_function<typename Operator::second_argument_type, typename Operator::result_type>
    {
        Operator op;
        typename Operator::first_argument_type value;
    
    public:
        bind1st(const Operator& x, const typename Operator::first_argument_type* y) : op(x), value(y) {}
        
        typename Operator::result_type operator()(typename Operator::second_argument_type& x) const
        {
            return op(value, x);
        }
    }
    
    template <class Operator, class T>
    inline binder1st<Operator> bind1st(const Operator& op, const T& x)
    {
        typedef typename Operator::first_argument_type arg1_type;
        return binder1st<Operator>(op, arg1_type(x));
    }
    template <class Operator>
    class binder2nd : public unary_function<typename Operator::first_argument_type, typename Operator::result_type>
    {
        Operator op;
        typename Operator::second_argument_type value;
    
    public:
        bind1st(const Operator& x, const typename Operator::second_argument_type* y) : op(x), value(y) {}
        
        typename Operator::result_type operator()(typename Operator::first_argument_type& x) const
        {
            return op(x, value);
        }
    }
    
    template <class Operator, class T>
    inline binder2nd<Operator> bind1st(const Operator& op, const T& x)
    {
        typedef typename Operator::second_argument_type arg2_type;
        return binder1st<Operator>(op, arg2_type(x));
    }
    • 对函数进行合成:compose1、compose2
    // h(x) = f(g(x))
    template <class Operation1, class Operation2>
    class unary_compose : public unary_function<typename Operation2::argument_type,
                                                typename Operation1::result_type>
    {
        Operation1 op1;
        Operation2 op2;
    public:
        unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {}
        
        typename Operation1::result_type operator()(typename Operation2::argument_type& x) const
        {
            return op1(op2(x));
        }
    }
    
    template <class Operation1, class Operation2>
    inline unary_compose<Operation1, Operation2>compose1(const Operation1& x, const Operation2& y)
    {
        return unary_compose<Operation1, Operation2>(op1, op2);
    }
    // h(x) = f(g1(x), g2(x))
    template <class Operation1, class Operation2, class Operation3>
    class binay_compose : public unary_function<typename Operation2::argument_type,
                                                typename Operation1::result_type>
    {
        Operation1 op1;
        Operation2 op2;
        Operation3 op3;
        
    public:
        binay_compose(const Operation1& x, const Operation2& y, cosnt Operation3& z) : op1(x), op2(y), op3(z) {}
        
        typename Operation1::result_type operator()(typename Operation2::argument_type& x) const
        {
            return op1(op2(x), op3(x));
        }
    }
    
    template <class Operation1, class Operation2, class Operation3>
    inline binay_compose<Operation1, Operation2, Operation3> compose2(const Operation1& x, const Operation2& y, cosnt Operation3& z)
    {
        return binay_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
    }
    • 用于函数的指针:包装一般函数,使得一般函数也可以适用于Function adapter中
    // 包装的函数只有一个参数
    template <class Arg, class Result>
    class pointer_to_unary_function : public unary_function<Arg, Result>
    {
        Result (*ptr)(Arg);
    
    public:
        
        explict pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {}
        
        Result operator()(Arg x) const
        {
            return ptr(x);
        }
    }
    
    template <class Arg, class Result>
    inline pointer_to_unary_function<Arg, Result>ptr_fun(Result (*ptr)(Arg))
    {
        return pointer_to_unary_function<Arg, Result>(x);
    }
    // 包装的函数有两个参数
    template <class Arg1, class Arg2, class Result>
    class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result>
    {
        Result (*ptr)(Arg1, Arg2);
    
    public:
        
        explict pointer_to_unary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {}
        
        Result operator()(Arg1 x, Arg2 y) const
        {
            return ptr(x, y);
        }
    }
    
    template <class Arg1, class Arg2, class Result>
    inline pointer_to_unary_function<Arg1, Arg2, Result>ptr_fun(Result (*ptr)(Arg1 x, Arg2 y))
    {
        return pointer_to_unary_function<Arg1, Arg2, Result>(x, y);
    }
    • 用于成员函数的指针:mem_fun、mem_fun_ref
      • mem_fun、mem_fun_ref修饰的成员函数不具备多态性质

    // 无参数成员函数调用,其他有参数函数的调用方式类似
    template <class S, class T>
    class mem_fun_t : public unary_function<T*, S>
    {
        S (T::*f)();
    public:
        explict mem_fun_t(S (T::*pf)()) : f(pf) {}
        
        S operator()(T* p) const
        {
            return (p->*f)();
        }
    }
    
    template <class S, class T>
    inline mem_fun_t<S, T> mem_fun(S (T::*f)())    
    {
        return mem_fun_t<S, T>(f);
    }
  • 相关阅读:
    Linux编程 22 shell编程(输出和输入重定向,管道,数学运算命令,退出脚本状态码)
    mysql 开发进阶篇系列 46 物理备份与恢复( xtrabackup的 选项说明,增加备份用户,完全备份案例)
    mysql 开发进阶篇系列 45 物理备份与恢复(xtrabackup 安装,用户权限,配置)
    mysql 开发进阶篇系列 44 物理备份与恢复( 热备份xtrabackup 工具介绍)
    Linux编程 21 shell编程(环境变量,用户变量,命令替换)
    Linux编程 20 shell编程(shell脚本创建,echo显示信息)
    mysql 开发进阶篇系列 43 逻辑备份与恢复(mysqldump 的基于时间和位置的不完全恢复)
    Linux编程 19 编辑器(vim 用法)
    (网页)angularjs中的interval定时执行功能(转)
    (网页)在SQL Server中为什么不建议使用Not In子查询(转)
  • 原文地址:https://www.cnblogs.com/chusiyong/p/11574336.html
Copyright © 2011-2022 走看看