2016-04-07 15 views
3

C++ 11のfunctionを使用してクラスメソッドへのマップを作成しようとしています。メソッドへのマップC++ 11

Cスタイルの関数ポインタ:
方法:

void MyClass::MyMethod(void*); 

地図宣言:

std::map<int, void (MyClass::*)(void*)> mapIdToMethod; 

地図のインサート:

mapIdToMethod.insert(std::make_pair(2, &MyClass::MyMethod)); 

メソッドの呼び出し:

MyClass mc; 
(mc.*mapIdToMethod.at(1))(nullptr); 

上記のコードは動作しますが、どのようにC++ 11のfunctionを使用するように変換できますか?私が試したよ何

マップ宣言:

std::map<int, function<void(void*)>> mapIdToMethod;//The map declare 

、私はどのように挿入し、このmap上のメソッドを呼び出すことができますか?

おそらく
+6

場合。 **壊れていない場合は修正しないでください** – bolov

+4

std :: functionは別のものです。元のコードはメンバ関数ポインタのみを格納します。 std :: functionでは、メンバ関数ポインタがクラスのインスタンスにバインドされている必要があります。 –

+3

関数MyMethodが何らかの内部状態を使用している場合は、それを[バインド](http://en.cppreference.com/w/cpp/utility/functional/bind)するか、ラムダを使用する必要があります。しかし、@ bolovが言っているように、動作すればそれを変更すべきではありません。少なくともstd :: functionはランタイムオーバーヘッドをそれに置きますので、そのままにしておきます。 – Incomputable

答えて

2

私もCスタイルのポインタ経由functionのファンですが、それはあなたがvoid (MyClass::*)(void*)用のアナログがfunction<void(MyClass&, void*)>であることを認識することが重要ですは、function<void(void*)>ではありません。あなたはMapIdToMethodbar.insert(make_pair(2, &MyClass::MyMethod))に挿入されたとして、あなたはこれまでと同じように挿入することができますが、あなたはまた、mem_fnを使用することができ、これはないだろう

map<int, function<void(MyClass&, void*)>> bar; 

:だからあなたはあなたが既にとMapIdToMethodに行くきまし複製することができMapIdToMethodに挿入するときに使用することが可能になっています

bar.insert(make_pair(2, mem_fn(&MyClass::MyMethod))); 

、あなたの質問に答えるために。与えられた:

map<int, function<void(void*)>> foo; 

あなたは、void*を取り、何も返さないメンバ関数を挿入が、あなたはすでにあなたが呼び出しがを構築するために希望するオブジェクトがある場合にのみすることができます。あなたはbindを使用していることを行うことができます:あなたはそれを持っているように、そのままにしておくのコードに問題がない

MyClass mc; 

foo.insert(make_pair(2, bind(&MyClass::MyMethod, mc, placeholders::_1))); 

Live Example

+0

こんにちは、ありがとうございました! – Evyatar

4

ないオリジナル多分読みやすいほど効率:

std::map<int, std::function<void (MyClass&,void*)>> mapIdToMethod;  
mapIdToMethod.emplace(2, [](MyClass& c,void* p){ c.MyMethod(p);}); 
// alternatively: 
using std::placeholders::_1;  
using std::placeholders::_2; 
mapIdToMethod.emplace(2,std::bind(&MyClass::MyMethod,_1,_2)); 

MyClass mc; 
mapIdToMethod.at(2)(mc, nullptr); 
+0

いいえ、読みにくいです。間違いなくC++ 11の機能を使用することは間違いありませんが、読むのは簡単ではありません。 – StoryTeller

+1

OPにC++ 11があれば、 'std :: bind'と' std :: placeholders :: _ 1'を使うことができます。 – juanchopanza

+0

@元食館:私は同意します。 – MarkusParker