5

C++で可能ですか?たとえば、パラメーターをとらず、戻り値の型が void である関数へのポインターがあります。

void (*f)();

および関数オブジェクト:

class A
{
public:
    void operator()() { cout << "functor\n"; }
};

オブジェクトfのアドレスに割り当てることはできますか? Aそして、ファンクターを呼び出すf()ために呼び出すときは?A

私はこれを試しましたが、うまくいきません:

#include <iostream>
using namespace std;

class A
{
public:
    void operator()() { cout << "functorA\n"; }
};

int main()
{
    A ob;
    ob();
    void (*f)();
    f = &ob;
    f();       // Call ob();
    return 0;
}

私は得るC:\Users\iuliuh\QtTests\functor_test\main.cpp:15: error: C2440: '=' : cannot convert from 'A *' to 'void (__cdecl *)(void)' There is no context in which this conversion is possible

これを達成する方法はありますか?

4

4 に答える 4

5

指定した方法でそれを行うことはできません。理由は次のとおりです。

  1. operator()は非静的関数である必要があります(標準要件)
  2. 非静的関数へのポインターには、暗黙のパラメーター(クラスインスタンスへのポインター)が必要です。
  3. f()を呼び出しても、関数が呼び出されたオブジェクトAのインスタンスは示されません。

Stephane Rollandが指摘したように、C++11とstd::functionを使用すると、うまくいく可能性があります。バインディングでオブジェクトへのポインターを指定します。

std::function<void(void)> f = std::bind(&A::operator(), &ob);

(メンバー関数でのstd :: functionの使用に関する質問を参照してください)

于 2013-02-01T09:35:27.453 に答える
3

C++11 を使用している場合は、std::functionを使用できます

#include <functional>

std::function<void()> f;

int main()
{
    A ob;
    ob();

    f = ob;    // f refers to ob
    f();       // Call ob();
    return 0;
}
于 2013-02-01T09:39:35.563 に答える
2

はい、C++1/C++0x 機能を使用して可能ですが、これを実現するには、関数とオブジェクト関数の 2 つのタイプに対応できるstd::functionを使用する必要があります。

#include <functional>

 class A
{
public:
    void operator()() { }
};

int main()
{
    std::function<void(void)> aFunction;
    A ob;

    aFunction = ob;

// or as another user said
// aFunction = std::bind(&A:operator(), &ob);

    aFunction();

    void (*f)();

    aFunction = f;

    aFunction();

    return 0;
}

C++03 に行き詰まっている場合はstd::mem_funstd::ptr_fun

于 2013-02-01T09:28:50.017 に答える
1

次のような回避策はどうでしょうか。

基本的に、メンバー関数と関数を呼び出す共通の方法が必要です。次に、関数またはメンバー関数のいずれかへの汎用ポインターを表すラッパーを作成できます。クラスがあり、すべての派生クラスBaseを呼び出せるようにしたいとします。operator()次にfunction()、同様に呼び出したいもあります。

class Base
{
public:
    virtual void operator()() = 0;
};

class A : public Base
{
public:
    void operator()(){ std::cout << "A()" << std::endl; }
};

void function()
{
    std::cout << "function" << std::endl; 
}

カスタム ポインターを作成できるラッパーを作成する場合 ( MyFncPtr):

typedef void (Base::*BaseFncPtr)();
typedef void (*FncPtr)();

class MyFncPtr
{
public:
    MyFncPtr(FncPtr f) : fnc(f), baseObj(NULL), baseFnc(NULL) { }
    MyFncPtr(BaseFncPtr fPtr, Base* objPtr) : baseFnc(fPtr), baseObj(objPtr), fnc(NULL)  { }
    void invoke()
    {
        if (baseObj && baseFnc)
            (baseObj->*baseFnc)();
        else if (fnc)
            fnc();
    }

private:
    BaseFncPtr baseFnc;
    Base* baseObj;
    FncPtr fnc;
};

次のように達成できます。

A a;
MyFncPtr myPtr(&Base::operator(), &a);
myPtr.invoke();
MyFncPtr myPtr2(function);
myPtr2.invoke();

出力:

A()
function

お役に立てれば :)

于 2013-02-01T10:24:57.897 に答える