Lambda関数funcPointer*
の出現により、C++11でbind
3つすべてを実際に実行できます。最初にそれぞれについて話し、彼らが何をしているのかを話し合いましょう。
funcPointer
オブジェクトを取り込まずにChild
メソッドを呼び出そうとするため、オブジェクトを保存する必要があります。子オブジェクトはポインタで保存できます:またはC ++ 14では値で保存できます:Child
Child
bind(&Child::TestFunc, this)
[arg = *this]() mutable { arg.TestFunc(); }
funcPointer2
Child
を使用してメソッドを呼び出そうとしますParent*
。これは次のように行うことができます。[](Parent* arg){ static_cast<Child*>(arg)->TestFunc(); }
もちろん、これは合法ではないので、実際には、ラムダを呼び出す前に検証できるポリモーフィック型を作成する場合は、が実際にあると(new Parent)->TestFunc()
想定しています。Parent*
Child*
Parent
[](Parent* arg) {
assert(dynamic_cast<Child*>(arg) != nullptr);
static_cast<Child*>(arg)->TestFunc();
}
funcPointer3
メソッドへのポインタを格納しようとしChild
ますが、すでにそれが機能しています。オブジェクトを使用しChild
て呼び出す必要があります。例:(this->*p.funcPointer3)()
。funcPointer3
ただし、次のように割り当てる必要がありますfuncPointer3 = &Child::TestFunc
。これを実行しようとするとfuncPointer3 = &TestFunc
、次のエラーが発生します。
'&':バインドされたメンバー関数式に対する不正な操作
次に、関数ポインターまたはメンバー関数ポインターを使用してクロージャー型を参照することはできないため、関数ポインターをfunction
オブジェクトに変換する必要があります。(これfuncPointer3
は単なるメンバー関数ポインターなので、変換する必要はありませんが、function
オブジェクトにメンバー関数ポインターを含めることができp.funcPointer(this)
、次の呼び出しを簡略化できることを示すために変換します。 ):
class Parent {
public:
function<void()> funcPointer;
function<void(Parent*)> funcPointer2;
function<void(Child*)> funcPointer3;
};
適応したので、1、2、および3Parent
で示すように簡単に割り当てることができます。
void Child::Do() {
Parent p;
p.funcPointer = bind(&Child::TestFunc, this);
p.funcPointer2 = [](Parent* arg) { static_cast<Child*>(arg)->TestFunc(); };
p.funcPointer3 = &Child::TestFunc;
p.funcPointer();
p.funcPointer2(this);
p.funcPointer3(this);
}
あなたはおそらくこれを知っていて、テストしているだけですが、で新しいオブジェクトを作成するのと同じくらい簡単に、Parent
から継承したのメンバーを使用することができます。これを切り替えて、例のコードをスローします:http: //ideone.com/yD7RomChild
Parent
Child::Do