ファンクタアダプター

functor-adaptor.png

すでに特定のクラスのメンバ関数になっている関数を渡したい場合がある。
しかし、メンバ関数は動作の対象となるオブジェクトへのポインタである「隠し」パラメータを取るのである。

エラー 63 error C2440: '=' : 'void (thiscall OnCheckedChangedListener::* )(const View &,bool)' から 'void (cdecl *)(const View &,bool)' に変換できません。

↑こんなエラーになっちゃうってこと。C2440
隠しパラメータってこういうこと。

void (*m_CallBackFunction)(const View&,bool);///< コールバック関数。関数ポインタ ボタンを押した時の挙動

が、

'void (__thiscall OnCheckedChangedListener::* )(const View &,bool)

になるってことね。

定義

STLで用意されているものである。
既存のメンバ関数をファンクタとして使用できるようにするテンプレートである。

種類

  1. mem_fun…ポインタを引数にとるメンバ関数に作用する。
  2. mem_fun_ref…オブジェクトまたは参照に引数をとるメンバ関数に作用する。
  3. ptr_fun…関数ポインタを引数に取るグローバス関数に作用する。

厳密に言えば、3.はほとんどの場合必要ない[1]

mem_fun1_t<戻り値, クラスの型名,引数> 関数オブジェクト変数名( &クラスの型名::呼びたいメンバ関数名 );

詳しくはfunctional

考察

2個以上の引数を持つメンバ関数はむり。構造体とか使って無理やり引数を1個にするしかなさそう。
boostmem_fnは2個以上の引数でもいいらしいよ。

サンプルコード

#include <stdio.h>
#include <iostream>
#include <functional> // ←mem_funを使うために必要
using namespace std;
class CThing {
public:
    int Func0() { return printf("This is Func0\n"); }
};
int main() {
    CThing thing;   // ここは、同じ。
    // thing のメンバー関数 Func0 を呼び出す。
    mem_fun(&CThing::Func0)(&thing);    // クラスオブジェクトを引数として与えて、それのメンバ関数を呼び出す。
    return 0;
}

引数付きの例

#include <iostream>
#include <functional> // ←mem_funを使うために必要
//#include <miffy/gl/ui/button.h>
using namespace std;
class A{
public:
      int hi( void ){ cout<<"return 77"<<endl;return 77; }
      int hi2( int a ){ cout<<"a is "<<a<<endl; return a; }
};
void main(){
    A a;
    //普通の呼び方
    a.hi();   // や、
    a.hi2( 88 );// として、呼び出していたところを、
    //コールバック
    mem_fun( &A::hi )( &a );// としたり、
    mem_fun1( &A::hi2 )( &a, 88 );// として、呼び出せるのである。
 
    // あるいは、↓のように、関数オブジェクトを明示的に作成しておき、
    mem_fun_t<int, A> functor( &A::hi );
    mem_fun1_t<int, A, int> functor_with_arg( &A::hi2 ); 
    //mem_fun1_t<戻り値, クラスの型名,引数> 関数オブジェクト変数名( &クラスの型名::呼びたいメンバ関数名 ); 
    functor( &a );// や、
    functor_with_arg( &a, 88 );// として、呼び出すこともできる。
 
    //CToggleButton toggle(vec2<int>(0,0),200,12,"a","b",0);
    //toggle.SetOnCheckedChanged
}

mem_fn mem_fun

サポートサイト Wikidot.com mem_fnmem_fun