C++11標準ライブラリのstd::function
やstd::bind
では、クラスのデータメンバ(メンバ変数)を格納できる。
#include <functional> struct A { int md; void mf(int v) { md = v * 2; } } a; // メンバ関数 A::mf (比較用) std::function<void (A&, int)> f1 = &A::mf; f1(a, 3); // a.mf(3) assert(a.md == 6); using std::placeholers::_1; std::function<void (int)> b1 = std::bind(&A::mf, std::ref(a), _1); b1(4); // a.mf(4) assert(a.md == 8); // データメンバ A::md std::function<int& (A&)> f2 = &A::md; f2(a) = 42; // a.md = 42 assert(a.md == 42); std::function<int& ()> b2 = std::bind(&A::md, std::ref(a)); b2() /= 2; // a.md /= 2 assert(a.md == 21);
Boostライブラリのfunction
とbind
も同等機能を有する(Boost 1.49.0で動作確認)。ただしboost::bind
の第一引数ではboost::function<int&(A&)>
への明示的なキャストが必要。ここまでして使う意義があるかは疑問...
#include <boost/function.hpp> a.md = 21; boost::function<int& (A&)> f2 = &A::md; f2(a) *= 2; assert(a.md == 42); // NG: boost::function<int& ()> b2 = boost::bind(&A::md, boost::ref(a)) boost::function<int& ()> b2 = boost::bind( boost::function<int& (A&)>(&A::md), boost::ref(a) ); b2() -= 10; assert(a.md == 32);
2012-03-08追記:boost::bind
の戻り値型R
=int&
を明示指定すれば良かった。(thanks to [twitter:@manga_osyo]さん)
boost::function<int& ()> b2 = boost::bind<int&>(&A::md, boost::ref(a));
N3337 20.8.2/p1, 20.8.11.2.4/p1-2より引用。(下線部は強調)
1 Define
INVOKE(f, t1, t2, ..., tN)
as follows:
(t1.*f)(t2, ..., tN)
whenf
is a pointer to a member function of a classT
andt1
is an object of typeT
or a reference to an object of typeT
or a reference to an object of a type derived fromT
;((*t1).*f)(t2, ..., tN)
whenf
is a pointer to a member function of a classT
andt1
is not one of the types described in the previous item;t1.*f
whenN == 1
andf
is a pointer to member data of a classT
andt1
is an object of typeT
or a reference to an object of typeT
or a reference to an object of a type derived fromT
;(*t1).*f
whenN == 1
andf
is a pointer to member data of a classT
andt1
is not one of the types described in the previous item;f(t1, t2, ..., tN)
in all other cases.
R operator()(ArgTypes... args) const
1 Effects:INVOKE(f, std::forward<ArgTypes>(args)..., R)
(20.8.2), wheref
is the target object (20.8.1) of*this
.
2 Returns: Nothing ifR
isvoid
, otherwise the return value ofINVOKE(f, std::forward<ArgTypes>(args)..., R)
.
関連URL