当前位置: 移动技术网 > IT编程>开发语言>C/C++ > STL学习_配接器篇

STL学习_配接器篇

2018年03月02日  | 移动技术网IT编程  | 我要评论

冲田杏梨17部作品,乌古的咒语有什么用,淮安信息职业技术学院教务频道

定义

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

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网