0

私はこのコードを持っています

class ClassX {};

class ClassY : public ClassX {};
typedef std::function<void (ClassX*)> myCaller;

class Foo {
    Foo()
    {
        createCaller(this, &Foo::bar); //line 22 with the error
    }

    template <typename Class>
    void createCaller(Class *obj, void (Class::*func)(ClassX*))
    {
         myCaller mc = std::bind(func, obj, std::placeholders::_1);;
    }

    void bar(ClassY* x)
    {
        printf("fooBrr");
    }

};

そして、barがClassXの代わりにClassXを拡張するClassYを取得するまでは正常に機能します。

コンパイル時エラーが発生します:main.cpp:22:9:「createCaller」の呼び出しに一致するメンバー関数がありません

問題は、barがClassXまたは任意のクラスを拡張する任意のクラスのパラメーターを取得できるようにするにはどうすればよいですか?それも可能ですか?

4

2 に答える 2

1

ClassYおよびその他の派生クラスの場合、次のことが簡単にできます。

#include <functional>

class ClassX {};

class ClassY : public ClassX {};

typedef std::function<void (ClassX*)> myCaller;

int main()
{
    myCaller f = [](ClassX*){};
    ClassY classY;
    f(&classY);
}

ただし、次の点に注意する必要があります。

  • ClassYオブジェクト自体ではなく、ClassYオブジェクトのアドレスを渡します。あなたはClassYに合格すると言いましたが、それは間違っています。
  • パラメータをであると宣言しているClassX*ため、poitnerをconstに渡さない可能性があります(つまりconst ClassY*、禁止されています)
  • コンパイラは、 ClassYがClassXから派生していることを認識している必要があるため、ClassYの定義(ヘッダー)を含める必要があります。
  • 関数を呼び出すコードは「isderived」プロパティにアクセスできる必要があるため、ClassYはClassXからpublicを派生させる必要があります(nitpickersの場合:はい、あります。protectedもちろんfriend、継承は複数レベルの継承を通じて間接的に行うことができます。 。)

しかし、これらはすべて、だけstd::functionでなく、関数一般にも当てはまります。ClassXから派生していない(表示可能でアクセス可能な)他のクラスの場合、関数を呼び出すことはできません。

于 2013-03-14T13:13:05.207 に答える
1

barより制限があるため、それを行うことはできませんmyCaller。ただし、別の方法で行うこともできます。

class ClassX {};

class ClassY : public ClassX {};
typedef std::function<void (ClassY*)> myCaller;

class Foo {
    Foo()
    {
        createCaller(this, &Foo::bar); //line 22 with the error
    }

    template <typename Class>
    void createCaller(Class *obj, void (Class::*func)(ClassX*))
    {
         myCaller mc = std::bind(func, obj, std::placeholders::_1);
    }

    void bar(ClassX* x)
    {
        printf("fooBrr");
    }

};

barこれで、制限が緩和され、myCallerバインドできるようになります。

barまた、aを取得しClassX*てdynamic_castし、ClassY*NULLをチェックすることもできます。

于 2013-03-15T12:31:43.867 に答える