• 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);
    }
  • 相关阅读:
    c# 扩展方法奇思妙用
    AnkhSVN的自动加锁
    C#数组学习
    同一IP下多端口网站共享cookie的问题
    瞎子摸象销售开票(一)
    瞎子摸象年结
    配置WSS3.0搜索功能的步骤
    瞎子摸象销售开票(二)
    瞎子摸象汇兑损益
    ajax+php鼠标拖动层至任意位置并实时保存
  • 原文地址:https://www.cnblogs.com/chusiyong/p/11574336.html
Copyright © 2020-2023  润新知