株式会社エス・スリー・フォー

STL Samples : <functional>

関数オブジェクト base

Sunary_function
Sbinary_function

- template <class Arg, class Result>
  struct unary_function {
    typedef Arg    argument_type;
    typedef Result result_type;
  };

- 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,binary_functionは単項/二項関数オブジェクトのベースとなるクラスです。

SOURCE

#include <iostream>
#include <functional>

using namespace std;

template<class T>
struct square : unary_function<T,T> {
  T operator()(const T& x) const {
    return x*x;
  }
};

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

void std_function() {
  cout << "unary_function, binary_function" << endl;
  cout << " 5 ^ 2  = " << square<int>()(5) << endl;
  cout << "|5 - 2| = " << diff<int>()(5,2) << endl;
}

算術演算

Splus

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

 T plus<T>::operator()(const T& x, const T& y) const;

x + y を返します。

Sminus

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

 T minus<T>::operator()(const T& x, const T& y) const;

x – y を返します。

Smultiplies

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

 T multilies<T>::operator()(const T& x, const T& y) const;

x * y を返します。

Sdivides

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

 T divides<T>::operator()(const T& x, const T& y) const;

x / y を返します。

Smodulus

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

 T modulus<T>::operator()(const T& x, const T& y) const;

x % y を返します。

Snegate

- template <class T>
  struct negate : unary_function<T,T> {
    T operator()(const T& x) const;
  };

 T negate<T>::operator()(const T& x) const;

-x を返します。

SOURCE

#include <iostream>
#include <functional>

using namespace std;

void std_arithmetic() {
  cout << "plus, minus, multiplies, divides, modulus, negate" << endl;
  cout << "10 + 3 = " << plus<int>()       (10,3) << endl;
  cout << "10 - 3 = " << minus<int>()      (10,3) << endl;
  cout << "10 * 3 = " << multiplies<int>() (10,3) << endl;
  cout << "10 / 3 = " << divides<int>()    (10,3) << endl;
  cout << "10 % 3 = " << modulus<int>()    (10,3) << endl;
  cout << "   - 3 = " << negate<int>()     (3)    << endl;
}

比較

Sequal_to

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

 bool equal_to<T>::operator()(const T& x, const T& y) const;

x == y を返します。

Snot_equal_to

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

 bool not_equal_to<T>::operator()(const T& x, const T& y) const;

x != y を返します。

Sgreater

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

 bool greater<T>::operator()(const T& x, const T& y) const;

x > y を返します。

Sless

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

 bool less<T>::operator()(const T& x, const T& y) const;

x < y を返します。

Sgreater_equal

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

 bool greater_equal<T>::operator()(const T& x, const T& y) const;

x >= y を返します。

Sless_equal

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

 bool less_equal<T>::operator()(const T& x, const T& y) const;

x <= y を返します。

SOURCE

#include <iostream>
#include <functional>

using namespace std;

void std_comparisons() {
  cout << "equal_to, not_equal_to, less, less_equal, greater, greater_equal" << endl;
  cout << boolalpha;
  cout << "10 == 3 " <<      equal_to<int>()(10,3) << endl;
  cout << "10 != 3 " <<  not_equal_to<int>()(10,3) << endl;
  cout << "10 <  3 " <<          less<int>()(10,3) << endl;
  cout << "10 <= 3 " <<    less_equal<int>()(10,3) << endl;
  cout << "10 >  3 " <<       greater<int>()(10,3) << endl;
  cout << "10 >= 3 " << greater_equal<int>()(10,3) << endl;
}

論理演算

Slogical_and

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

 bool logical_and<T>::operator()(const T& x, const T& y) const;

x && y を返します。

Slogical_or

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

 bool logical_or<T>::operator()(const T& x, const T& y) const;

x || y を返します。

Slogical_not

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

 bool logical_not<T>::operator()(const T& x) const;

!x を返します。

SOURCE

#include <iostream>
#include <functional>

using namespace std;

void std_logical() {
  cout << "logical_and, logical_or, logical not" << endl;
  cout << boolalpha;
  cout << "true && false = " << logical_and<bool>()(true,false) << endl;
  cout << "true || false = " <<  logical_or<bool>()(true,false) << endl;
  cout << "      ! false = " << logical_not<bool>()(false)      << endl;
}

論理反転

Sunary_negateFnot1

- template <class Predicate>
  class unary_negate
    : public unary_function<typename Predicate::argument_type,bool> {
  public:
    explicit unary_negate(const Predicate& pred);
    bool operator()(const typename Predicate::argument_type& x) const;
  };

 bool unarey_negate<Predicate>::operator()(
          const typename Predicate::argument_type& x) const;

!pred(x) を返します。

- template <class Predicate>
  unary_negate<Predicate>
  not1(const Predicate& pred);

unary_negate<Predicate>(pred) を返します。

Sbinary_negateFnot2

- template <class Predicate>
  class binary_negate
    : public binary_function<typename Predicate::first_argument_type,
        typename Predicate::second_argument_type, bool> {
  public:
    explicit binary_negate(const Predicate& pred);
    bool operator()(const typename Predicate::first_argument_type&  x,
        const typename Predicate::second_argument_type& y) const;
  };

 bool binary_negate<Predicate>::operator()(
          const typename Predicate::first_argument_type&  x,
          const typename Predicate::second_argument_type& y) const;

!pred(x,y) を返します。

- template <class Predicate>
  binary_negate<Predicate>
  not2(const Predicate& pred);

binary_negate<Predicate>(pred) を返します。

SOURCE

#include <iostream>
#include <functional>

using namespace std;

struct odd : unary_function<int,bool> {
  bool operator()(int x) const
    { return x%2 != 0; }
};

struct both_odd : binary_function<int,int,bool> {
  bool operator()(int x, int y) const {
    odd t;
    return t(x) && t(y);
  }
};

void std_negators() {
  cout << "unary_negate, not1, binary_negate, not2" << endl;
  odd o;
  unary_negate<odd> e(o);
  cout << boolalpha;
  cout << "3 は奇数: " << o(3) << endl;
  cout << "3 は偶数: " << e(3) << endl;
  cout << "4 は偶数: " << not1(o)(4) << endl;
  both_odd bo;
  binary_negate<both_odd> be(bo);
  cout << "4も6も奇数:     " << bo(4,6) << endl;
  cout << "4または6は偶数: " << be(4,6) << endl;
  cout << "4または7は偶数: " << not2(bo)(4,7) << endl;
}

バインダ

Cbinder1stFbind1st

- 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);
    typename Operation::result_type
      operator()(const typename Operation::second_argument_type& x) const;
  };

 typename Operation::result_type
 binder1st<Operation>::operator()(
          const typename Operation::second_argument_type& x) const;

op(value,x) を返します。

- template <class Operation, class T>
  binder1st<Operation>
  bind1st(const Operation& op, const T& x);

binder1st<Operation>(op, typename Operation::first_argument_type(x)) を返します。

Cbinder2ndFbind2nd

- 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);
    typename Operation::result_type
      operator()(const typename Operation::first_argument_type& x) const;
  };

 typename Operation::result_type
 binder2nd<Operation>::operator()(
        const typename Operation::first_argument_type& x) const;

op(x,value) を返します。

- template <class Operation, class T>
  binder2nd<Operation>
  bind2nd(const Operation& op, const T& x);

binder2nd<Operation>(op, typename Operation::second_argument_type(x)) を返します。

SOURCE

#include <iostream>
#include <functional>

using namespace std;

void std_binders() {
  cout << "binder1st, bind1st, binder2nd, bind2nd" << endl;
  minus<int> m;
  binder1st< minus<int> > one_minus_x(m,1);
  binder2nd< minus<int> > x_minus_one(m,1);
  cout << "1 - 5 = " << one_minus_x(5) << endl;
  cout << "5 - 1 = " << x_minus_one(5) << endl;
  cout << "3 - 5 = " << bind1st(minus<int>(),3)(5) << endl;
  cout << "5 - 3 = " << bind2nd(minus<int>(),3)(5) << endl;
}

関数ポインタ

Cpointer_to_unary_function

- template <class Arg, class Result>
  class pointer_to_unary_function : public unary_function<Arg, Result> {
  public:
    explicit pointer_to_unary_function(Result (*f)(Arg));
    Result operator()(Arg x) const;
  };

 Result pointer_to_unary_function<Arg,Result>::operator()(Arg x) const;

f(x) を返します。

Cpointer_to_binary_function

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

 Result pointer_to_binary_function<Arg1,Arg2,,Result>::operator()(
             Arg1 x, Arg2 y) const;

f(x,y) を返します。

Fptr_fun

- template <class Arg, class Result>
  pointer_to_unary_function<Arg, Result>
  ptr_fun(Result (*f)(Arg));

pointer_to_unary_function<Arg, Result>(f) を返します。

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

pointer_to_binary_function<Arg1,Arg2,Result>(f) を返します。

SOURCE

#include <iostream>
#include <functional>

using namespace std;

ostream& print_int(int x) {
  return cout << x;
}

ostream& print_int_int(int x, int y) {
  return cout << x << ',' << y;
}

void std_ptr_fun() {
  cout << "pointer_to_unary_function, pointer_to_binary_function, ptr_fun" << endl;
  pointer_to_unary_function<int,ostream&> pi(print_int);
  pi(5) << endl;
  ptr_fun(print_int)(5) << endl;
  pointer_to_binary_function<int,int,ostream&> pii(print_int_int);
  pii(10,20) << endl;
  ptr_fun(print_int_int)(10,20) << endl;
}

メンバ関数ポインタ

Cmem_fun_t

- template <class S, class T>
  class mem_fun_t : public unary_function<T*, S> {
  public:
    explicit mem_fun_t(S (T::*f)());
    S operator()(T* p) const;
  };

 S mem_fun_t<S,T>::operator()(T* p) const;

(p->*f)() を返します。

Cmem_fun1_t

- template <class S, class T, class A>
  class mem_fun1_t : public binary_function<T*, A, S> {
  public:
    explicit mem_fun1_t(S (T::*f)(A));
    S operator()(T* p, A x) const;
  };

S mem_fun1_t<S,T,A>::operator()(T* p, A x) const;

(p->*f)(x) を返します。

Cmem_fun_ref_t

- template <class S, class T>
  class mem_fun_ref_t : public unary_function<T, S> {
  public:
    explicit mem_fun_ref_t(S (T::*f)());
    S operator()(T& p) const;
  };

 S mem_fun_ref_t<S,T>::operator()(T& p) const;

(p.*f)() を返します。

Cmem_fun1_ref_t

- template <class S, class T, class A>
  class mem_fun1_ref_t : public binary_function<T, A, S> {
  public:
    explicit mem_fun1_ref_t(S (T::*f)(A));
    S operator()(T& p, A x) const;
  };

 S mem_fun1_ref_t<S,T,A>::operator()(T& p, A x) const;

(p.*f)(x) を返します。

Cconst_mem_fun_t

- template <class S, class T>
  class const_mem_fun_t : public unary_function<T*, S> {
  public:
    explicit const_mem_fun_t(S (T::*f)() const);
    S operator()(const T* p) const;
  };

 S const_mem_fun_t<S,T>::operator()(const T* p) const;

(p->*f)() を返します。

Cconst_mem_fun1_t

- template <class S, class T, class A>
  class const_mem_fun1_t : public binary_function<T*, A, S> {
  public:
    explicit const_mem_fun1_t(S (T::*p)(A) const);
    S operator()(const T* p, A x) const;
  };

 S const_mem_fun_t<S,T>::operator()(const T* p, A x) const;

(p->*f)(x) を返します。

Cconst_mem_fun_ref_t

- template <class S, class T>
  class const_mem_fun_ref_t : public unary_function<T, S> {
  public:
    explicit const_mem_fun_ref_t(S (T::*f)() const);
    S operator()(const T& p) const;
  };

 S const_mem_fun_ref_t<S,T>::operator()(const T& p) const;

(p.*f)() を返します。

Cconst_mem_fun1_ref_t

- template <class S, class T, class A>
  class const_mem_fun1_ref_t : public binary_function<T, A, S> {
  public:
    explicit const_mem_fun1_ref_t(S (T::*f)(A) const);
    S operator()(const T& p, A x) const;
  };

 S const_mem_fun1_ref_t<S,T,A>::operator()(const T& p, A x) const;

(p.*f)(x) を返します。

Fmem_fun

- template<class S, class T>
  const_mem_fun_t<S,T>
  mem_fun(S (T::*f)() const);

const_mem_fun_t<S,T>(f) を返します。

- template<class S, class T, class A>
  const_mem_fun1_t<S,T,A>
  mem_fun(S (T::*f)(A) const);

const_mem_fun1_t<S,T,A>(f) を返します。

Fmem_fun_ref

- template<class S, class T>
  const_mem_fun_ref_t<S,T>
  mem_fun_ref(S (T::*f)() const);

const_mem_fun_ref_t<S,T>(f) を返します。

- template<class S, class T, class A>
  const_mem_fun1_ref_t<S,T,A>
  mem_fun_ref(S (T::*f)(A) const);

const_mem_fun1_ref_t<S,T,A>(f) を返します。

SOURCE

#include <iostream>
#include <functional>

using namespace std;

class X {
  int N;
public:
  X(int n) : N(n) {}
  int times(int n) { return n*N; }
  int get() { return N; }
};

/* visual C++ では 1引数を持つメンバに対するアダプタは
 *
 * template<class R, class T, class A>
 *    mem_fun1_t<R, T, A> mem_fun1(R (T::*pm)(A));
 *
 * template<class R, class T, class A>
 *    mem_fun1_ref_t<R, T, A> mem_fun1_ref(R (T::*pm)(A));
 *
 * と宣言されている。
 *
 * また、constメンバニ対するアダプタは提供されていない。
 */

void std_mem_ptr() {
  cout << "mem_fun_t, mem_fun1_t, mem_fun, mem_fun_ref_t, mem_fun1_ref_t, mem_fun_ref" << endl;
  X x(5);

  mem_fun_t<int,X> t0(&X::get);
  mem_fun1_t<int,X,int> t1(&X::times);
  cout << t0(&x) << endl;
  cout << mem_fun(&X::get)(&x) << endl;
  cout << t1(&x, 2) << endl;
  cout << mem_fun1(&X::times)(&x,2) << endl;

  mem_fun_ref_t<int,X> r0(&X::get);
  mem_fun1_ref_t<int,X,int> r1(&X::times);
  cout << r0(x) << endl;
  cout << mem_fun_ref(&X::get)(x) << endl;
  cout << r1(x, 2) << endl;
  cout << mem_fun1_ref(&X::times)(x,2) << endl;
}