欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

STL学习_配接器篇

程序员文章站 2022-04-14 10:49:25
定义 配接器(Adapter)在STL组件的灵活组合运用功能上,扮演着轴承、转换器的角色。它事实上是一种设计模式。即将一个class的接口转换为另一个class的接口,使原本因接...

定义

配接器(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); }