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: No matching member function for call to 'createCaller'

问题是我将如何允许 bar 获取扩展 ClassX 的任何类或任何类的参数?有可能吗?

4

2 回答 2

1

你不能这样做,因为它barmyCaller. 但是,您可以采用另一种方式:

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将 aClassX*和 dynamic_cast 它转换为 aClassY*并检查 NULL。

于 2013-03-15T12:31:43.867 回答
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*,因此不能将指针传递给 const (即被const ClassY*禁止)
  • 编译器必须知道ClassY 是从 ClassX 派生的,因此您必须包含 ClassY 的定义(标头)。
  • 您调用该函数的代码必须有权访问“派生”属性,因此 ClassY 应该从 ClassX派生公共protected(对于挑剔者:是的,有friend,当然还有继承可以通过多级继承间接实现.. .)

但所有这些不仅适用于std::function,而且适用于一般的函数。对于不从 ClassX 派生(可见和可访问)的任何其他类,您不能调用该函数。

于 2013-03-14T13:13:05.207 回答