2

以下のコード (コメントを参照してください):

#include "stdafx.h"

#include <iostream>
using std::cout;

struct Base
{
 void fnc()
 {
  cout << "Base::fnc()";
 }

};

struct Impl
{
 void* data_;
 Impl(void (Base::*fp)())
 {
  fp();//HERE I'M INVOKING IT - I'M DOING SOMETHING WRONG!
 }
};
int _tmain(int argc, _TCHAR* argv[])
{
 return 0;
}  

エラー
「エラー 1 エラー C2064: 用語は、0 引数を取る関数として評価されません」

4

5 に答える 5

5

fp関数ポインターではなくメンバーポインターであるため、機能しません。

修正方法は簡単です。使用する必要があるので使用してください。someinstance.*fp();

于 2010-10-25T17:08:53.610 に答える
2

問題は、そうでないときに、関数をフリー関数として呼び出していることです。これはメンバー関数であり、オブジェクトのコンテキストで呼び出す必要があります。

(obj.*f)();

Boost.Bind は、これに取り組む慣用的な方法を提供します。

#include<boost/bind.hpp>

// ...
Impl i(boost::bind(&Base::fnc, obj));

Impl次のようにコンストラクタを定義できます。

#include<boost/function.hpp>

// ...
Impl(boost::function<void ()> fnc)
{
    fnc();  // boost::bind translates it to obj.fnc()
}

オブジェクトのみがImpl関数を呼び出すオブジェクトを認識している場合は、Boost.Bind のプレースホルダーを使用できます。

Impl i(boost::bind(&Base::fnc, boost::_1));

そして、Implコンストラクタは次のようになります

Impl(boost::function<void (Base)> fnc, Base& b)
{
    fnc(b);  // boost::bind translates it to b.fnc()
}

ファンクターを受け入れる側でテンプレートを使用する方が賢明な場合があります。

template<class Op>
Impl(Op fnc) { ... }

クライアントはブーストの有無にかかわらず、任意のメンバー関数を渡すことができるためです。ただし、その代償として、コンパイラのエラー メッセージがわかりにくくなる可能性があります。

于 2010-10-25T17:44:49.437 に答える
1

メンバー関数へのポインターに関するこのFAQを読むと役立つ場合があります。特に、これらの呼び出しに対してマクロを定義することを強くお勧めします。

#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))

于 2010-10-25T17:28:22.993 に答える
1
typedef  int (MyClass::*memberPointer_t)(int);

...

memberPointer_t mb = &MyClass::function;
MyClass* object = getObject();

int returnValue = (object->*mb)(3);

...

これはメンバー関数へのポインターであるため、オブジェクトで呼び出し、 ->* または .* 演算子を使用して呼び出す必要があります。

于 2010-10-25T17:24:18.037 に答える
1

関数を呼び出すには Base が必要です。

インスタンスとメンバー関数を関数のように呼び出すことができるファンクターにバインドできるようにする bind() や function<> のようなものを探しているかもしれません。

于 2010-10-25T17:05:36.627 に答える