C++ STL/functional

header < functional >

函数对象 利用操作符()的重载,使对象实现类似函数的功能,通常被用来做其他函数的谓词或者比较函数参数

1.基类

1.unary_function 一元函数模板
template <class Arg, class Result>
  struct unary_function {
    typedef Arg argument_type;
    typedef Result result_type;
  };

一元函数模板中的Arg代表operator()函数的唯一的参数的类型,Result代表operator()函数的返回值的类型。

// unary_function example
#include <iostream>     // std::cout, std::cin
#include <functional>   // std::unary_function

struct IsOdd : public std::unary_function<int,bool> {
  bool operator() (int number) {return (number%2!=0);}
};

int main () {
  IsOdd IsOdd_object;
  IsOdd::argument_type input;
  IsOdd::result_type result;

  std::cout << "Please enter a number: ";
  std::cin >> input;

  result = IsOdd_object (input);

  std::cout << "Number " << input << " is " << (result?"odd":"even") << ".\n";

  return 0;
}

output:
Please enter a number: 2
Number 2 is even.
2.binary_function
template <class Arg1, class Arg2, class Result>
  struct binary_function {
    typedef Arg1 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Result result_type;
  };
类似unary_function的用法

2.操作符模板类

1.算数操纵符
**plus:**
template <class T> struct plus : binary_function <T,T,T>
 {
  T operator() (const T& x, const T& y) const {return x+y;}
};
//适用于transform和accumulate算法的参数

**minus:**
template <class T> struct minus : binary_function <T,T,T> {
  T operator() (const T& x, const T& y) const {return x-y;}
};

//mutiplies,divide,modulus(相当于取余运算),negate(取一个数的相反数x->(-x))
2.关系操作符
equal_to:
template <class T> struct equal_to : binary_function <T,T,bool> {
  bool operator() (const T& x, const T& y) const {return x==y;}
};

not_equal_to:
template <class T> struct not_equal_to : binary_function <T,T,bool> {
  bool operator() (const T& x, const T& y) const {return x!=y;}
};
类似的还有greater,less,greater_equal,less_equal
3.逻辑操作符
logical_and:
template <class T>struct logical_and : binary_function <T,T,bool>
 {
  bool operator() (const T& x, const T& y) const {return x&&y;}
};

loical_or:
template <class T> struct logical_or : binary_function <T,T,bool> {
  bool operator() (const T& x, const T& y) const {return x||y;}
};

logical_not:
template <class T> struct logical_not : unary_function <T,bool> {
  bool operator() (const T& x) const {return !x;}
};

3.适配和转换函数

1.not1
template <class Predicate> unary_negate<Predicate> not1 (const Predicate& pred)
{
  return unary_negate<Predicate>(pred);
}


// not1 example
#include <iostream>     // std::cout
#include <functional>   // std::not1
#include <algorithm>    // std::count_if

struct IsOdd {
  bool operator() (const int& x) const {return x%2==1;}
  typedef int argument_type;
};

int main () {
  int values[] = {1,2,3,4,5};
  int cx = std::count_if (values, values+5, std::not1(IsOdd()));
  std::cout << "There are " << cx << " elements with even values.\n";
  return 0;
}

Output:
There are 2 elements with even values.
2.not2
template <class Predicate> binary_negate<Predicate> not2 (const Predicate& pred)
{
  return binary_negate<Predicate>(pred);
}

// not2 example
#include <iostream>     // std::cout
#include <functional>   // std::not2, std::equal_to
#include <algorithm>    // std::mismatch
#include <utility>      // std::pair

int main () {
  int foo[] = {10,20,30,40,50};
  int bar[] = {0,15,30,45,60};
  std::pair<int*,int*> firstmatch,firstmismatch;
  firstmismatch = std::mismatch (foo, foo+5, bar, std::equal_to<int>());
  firstmatch = std::mismatch (foo, foo+5, bar, std::not2(std::equal_to<int>()));
  std::cout << "First mismatch in bar is " << *firstmismatch.second << '\n';
  std::cout << "First match in bar is " << *firstmatch.second << '\n';
  return 0;
}

First mismatch in bar is 0
First match in bar is 30
3.bind1st
template <class Operation, class T>
  binder1st<Operation> bind1st (const Operation& op, const T& x);

// bind1st example
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;

int main () {
  int numbers[] = {10,20,30,40,50,10};
  int cx;
  cx = count_if (numbers, numbers+6, bind1st(equal_to<int>(),10) );
  cout << "There are " << cx << " elements that are equal to 10.\n";
  return 0;
}


There are 2 elements that are equal to 10.
4.bind2nd
template <class Operation, class T>
  binder2nd<Operation> bind2nd (const Operation& op, const T& x);


// bind2nd example
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;

int main () {
  int numbers[] = {10,-20,-30,40,-50};
  int cx;
  cx = count_if ( numbers, numbers+5, bind2nd(less<int>(),0) );
  cout << "There are " << cx << " negative elements.\n";
  return 0;
}

There are 3 negative elements.
5.ptr_fun
template <class Arg, class Result>
  pointer_to_unary_function<Arg,Result> ptr_fun (Result (*f)(Arg));


template <class Arg1, class Arg2, class Result>
  pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun (Result (*f)(Arg1,Arg2));


// ptr_fun example
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstdlib>
#include <numeric>
using namespace std;

int main () {
  char* foo[] = {"10","20","30","40","50"};
  int bar[5];
  int sum;
  transform (foo, foo+5, bar, ptr_fun(atoi) );
  sum = accumulate (bar, bar+5, 0);
  cout << "sum = " << sum << endl;
  return 0;
}

sum = 150
6.mem_fun
函数指针转化为函数对象
template <class S, class T> mem_fun_t<S,T> mem_fun (S (T::*f)());
template <class S, class T, class A> mem_fun1_t<S,T,A> mem_fun (S (T::*f)(A));
template <class S, class T> const_mem_fun_t<S,T> mem_fun (S (T::*f)() const);
template <class S, class T, class A> const_mem_fun1_t<S,T,A> mem_fun (S (T::*f)(A) const);

// mem_fun example
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

int main () {
  vector <string*> numbers;

  // populate vector of pointers:
  numbers.push_back ( new string ("one") );
  numbers.push_back ( new string ("two") );
  numbers.push_back ( new string ("three") );
  numbers.push_back ( new string ("four") );
  numbers.push_back ( new string ("five") );

  vector <int> lengths ( numbers.size() );

  transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fun(&string::length));

  for (int i=0; i<5; i++) {
    cout << *numbers[i] << " has " << lengths[i] << " letters.\n";
  }

  // deallocate strings:
  for (vector<string*>::iterator it = numbers.begin(); it!=numbers.end(); ++it)
    delete *it;

  return 0;
}

one has 3 letters.
two has 3 letters.
three has 5 letters.
four has 4 letters.
five has 4 letters.
7.mem_fun_ref

当容器中存放的是对象实体的时候用mem_fun_ref,当容器中存放的是对象的指针的时候用mem_fun。

// mem_fun_ref example
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

int main () {
  vector<string> numbers;

  // populate vector:
  numbers.push_back("one");
  numbers.push_back("two");
  numbers.push_back("three");
  numbers.push_back("four");
  numbers.push_back("five");

  vector <int> lengths (numbers.size());

  transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fun_ref(&string::length));

  for (int i=0; i<5; i++) {
      cout << numbers[i] << " has " << lengths[i] << " letters.\n";
  }
  return 0;
}

该例子中string没有*是实体,而mem_fun的例子中string* 容器中放的是string对象的指针.

4.工具类型

1.unary_negate
// unary_negate example
#include <iostream>     // std::cout
#include <functional>   // std::unary_negate
#include <algorithm>    // std::count_if

struct IsOdd_class {
  bool operator() (const int& x) const {return x%2==1;}
  typedef int argument_type;
} IsOdd_object;

int main () {
  std::unary_negate<IsOdd_class> IsEven_object (IsOdd_object);
  int values[] = {1,2,3,4,5};
  int cx;
  cx = std::count_if ( values, values+5, IsEven_object );
  std::cout << "There are " << cx << " elements with even values.\n";
 `
return 0;
}

There are 2 elements with even values
2.binary_negate
template <class Predicate> class binary_negate
  : public binary_function <typename Predicate::first_argument_type,
                            typename Predicate::second_argument_type, bool>
{
protected:
  Predicate fn_;
public:
  explicit binary_negate ( const Predicate& pred ) : fn_ (pred) {}
  bool operator() (const typename Predicate::first_argument_type& x,
                   const typename Predicate::second_argument_type& y) const
  { return !fn_(x,y); }
};

// binary_negate example
#include <iostream>     // std::cout
#include <functional>   // std::binary_negate, std::equal_to
#include <algorithm>    // std::mismatch
#include <utility>      // std::pair

int main () {
  std::equal_to<int> equality;
  std::binary_negate < std::equal_to<int> > nonequality (equality);
  int foo[] = {10,20,30,40,50};
  int bar[] = {0,15,30,45,60};
  std::pair<int*,int*> firstmatch,firstmismatch;
  firstmismatch = std::mismatch (foo,foo+5,bar,equality);
  firstmatch = std::mismatch (foo,foo+5,bar,nonequality);
  std::cout << "First mismatch in bar is " << *firstmismatch.second << "\n";
  std::cout << "First match in bar is " << *firstmatch.second << "\n";
  return 0;
}

First mismatch in bar is 0
First match in bar is 30
3.binder1st/binder2nd

分别是绑定第一个和第二个参数

template <class Operation> class binder1st
  : public unary_function <typename Operation::second_argument_type,
                           typename Operation::result_type>
{
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); }
};

// binder1st example
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;

int main () {
  binder1st < equal_to<int> > equal_to_10 (equal_to<int>(),10);
  int numbers[] = {10,20,30,40,50,10};
  int cx;
  cx = count_if (numbers,numbers+6,equal_to_10);
  cout << "There are " << cx << " elements equal to 10.\n";
  return 0;
}

There are 2 elements equal to 10.

binder2nd
template <class Operation> class binder2nd
  : public unary_function <typename Operation::first_argument_type,
                           typename Operation::result_type>
{
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); }
};
其他类似binder1st
4.pointer_to_unary_function/pointer_to_binary_function
pointer_to_unary_function
template <class Arg, class Result>
  class pointer_to_unary_function : public unary_function <Arg,Result>
{
protected:
  Result(*pfunc)(Arg);
public:
  explicit pointer_to_unary_function ( Result (*f)(Arg) ) : pfunc (f) {}
  Result operator() (Arg x) const
    { return pfunc(x); }
};

pointer_to_binary_function
template <class Arg1, class Arg2, class Result>
  class pointer_to_binary_function : public binary_function <Arg1,Arg2,Result>
{
protected:
  Result(*pfunc)(Arg1,Arg2);
public:
  explicit pointer_to_binary_function ( Result (*f)(Arg1,Arg2) ) : pfunc (f) {}
  Result operator() (Arg1 x, Arg2 y) const
    { return pfunc(x,y); }
};

例子:
// pointer_to_binary_function example
#include <iostream>
#include <functional>
#include <algorithm>
#include <cmath>
using namespace std;

int main () {
  pointer_to_binary_function <double,double,double> PowObject (pow);
  double numbers[] = {1.0, 2.0, 3.0, 4.0, 5.0};
  double squares[5];
  transform (numbers, numbers+5, squares, bind2nd(PowObject,2) );
  for (int i=0; i<5; i++)
    cout << squares[i] << " ";
  cout << endl;
  return 0;
}
5.const代表成员函数是否为const;fun后有1代表单个参数成员函数,没有1代表无参成员函数;ref和pointer代表是指针还是对象实体(这些类模板分别是对应的去掉_t的类模板的函数对象的类型)
  • mem_fun_t/mem_fun1_t
  • const_mem_fun_t/const_mem_fun1_t
  • mem_fun_ref_t/mem_fun1_ref_t
  • const_mem_fun_ref_t/const_mem_fun1_ref_t
template <class S, class T>
  class mem_fun_t : public unary_function <T*,S>
{
  S (T::*pmem)();//const加在这里表示const成员函数
public:
  explicit mem_fun_t ( S (T::*p)() ) : pmem (p) {}
  S operator() (T* p) const
    { return (p->*pmem)(); }
};

其他类似.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值