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);
}
原文地址:https://www.cnblogs.com/chusiyong/p/11574336.html