C++ STL/functional

来源:互联网 发布:网络小额信贷 编辑:程序博客网 时间:2024/06/09 22:57

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_functionstruct 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: 2Number 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_ifstruct 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::pairint 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 0First 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_ifstruct 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::pairint 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 0First 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.binder2ndtemplate <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_functiontemplate <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_functiontemplate <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 0
原创粉丝点击