STL Samples : <functional>
関数オブジェクト base
unary_function
binary_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は単項/二項関数オブジェクトのベースとなるクラスです。
#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; }
算術演算
- 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 を返します。
- 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 を返します。
- 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 を返します。
- 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 を返します。
- 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 を返します。
- template <class T>
struct negate : unary_function<T,T> {
T operator()(const T& x) const;
};
T negate<T>::operator()(const T& x) const;
-x を返します。
#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;
}
比較
- 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 を返します。
- 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 を返します。
- 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 を返します。
- 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 を返します。
- 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 を返します。
- 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 を返します。
#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;
}
論理演算
- 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 を返します。
- 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 を返します。
- 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 を返します。
#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;
}
論理反転
- 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) を返します。
- 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) を返します。
#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;
}
バインダ
- 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)) を返します。
- 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)) を返します。
#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;
}
関数ポインタ
- 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) を返します。
- 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) を返します。
- 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) を返します。
#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;
}
メンバ関数ポインタ
- 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)() を返します。
- 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) を返します。
- 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)() を返します。
- 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) を返します。
const_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)() を返します。
const_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) を返します。
const_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)() を返します。
const_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) を返します。
- 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) を返します。
- 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) を返します。
#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;
}