4

Test独特のデータ構造を持つクラスがあります。クラスのメンバーTestはastd::mapであり、キーはastd::stringであり、マップされた値はstruct次のように定義されます。

typedef struct {
  void (Test::*f) (void) const;
} pmf_t;

マップの初期化はOKです。問題は、指定された関数を呼び出そうとしているときです。問題を再現したおもちゃの例を作りました。ここにあります:

#include <iostream>
#include <map>

using namespace std;

class Test;
typedef void (Test::*F) (void) const;
typedef struct {
  F f;
} pmf_t;


class Test
{
public:
  Test () {
    pmf_t pmf = {
      &Test::Func
    };
    m["key"] = pmf;
  }
  void Func (void) const {
    cout << "test" << endl;
  }
  void CallFunc (void) {
    std::map<std::string, pmf_t>::iterator it = m.begin ();
    ((*it).second.*f) (); // offending line
  }

  std::map<std::string, pmf_t> m;
};


int main ()
{

  Test t;
  t.CallFunc ();

  return 0;
}

よろしくお願いします、ジル

4

5 に答える 5

5

pmf_tタイプの名前はです。f最初の変更は、を削除し*て取得することsecond.fです。それはあなたにメンバーへのポインタの値を与えます。メンバーへのポインタを使用するには、インスタンスが必要です。正しいタイプで使用できるのは、だけなthisので、->*演算子で使用します。

(this->*it->second.f)();

全体を括弧で囲む必要があります。そうしないと、コンパイラは、呼び出しようとしていると判断しit->second.f()(許可されていません)、結果をに適用し->*ます。

于 2011-07-27T15:19:57.457 に答える
3

問題のある行は、呼び出すオブジェクトなしでメンバー関数を呼び出そうとしています。thisオブジェクトに対してそれを呼び出すことを意図している場合、呼び出しは次のようになります。

( this->* ((*it).second.f) )(); 

this->*現在のオブジェクトのメンバーへのポインタを逆参照するための構文はどこにありますか。((*it).second.f)マップから取得したポインタであり、()実際に関数を呼び出すための呼び出し演算子です。

これはおそらく演習としては良いことですが、それ以外の場合は使用が制限されます。

于 2011-07-27T15:23:36.377 に答える
1

これに関するC++FAQを確認することをお勧めします。構文を正しく理解するのは明らかに難しいです(実際にはマクロの使用をお勧めします)。

于 2011-07-27T15:13:37.097 に答える
1

これを試して:

(this->*((*it).second.f)) ();
于 2011-07-27T15:22:48.373 に答える
1

この質問には遅すぎるかもしれませんが、一見複雑に見えるシナタックスは2つの単純な行に分割できるため、かなり明確に見えます。

void CallFunc (void) 
{
     pmf_t t = m["key"]; //1>get the data from key
    (this->*t.f)();      //2>standard procedure to call pointer to member function
}
于 2011-07-27T15:52:29.517 に答える