1
#include <iostream>
using namespace std;

class B
{
public:
  int getMsg(int i)
  {
    return i + 1;
  }
};

class A
{
  B b;
public:
  void run()
  {
    taunt(b.getMsg);
  }

  void taunt(int (*msg)(int))
  {
    cout << (*msg)(1) << endl;
  }
};

int main()
{
  A a;
  a.run();
}

上面的代码在 A 类中有一个 B 类,A 类有一个方法 taunt,它接受一个函数作为参数。B 类的 getMsg 被传递到 taunt...上面的代码生成了以下错误消息:“错误:没有匹配函数调用 'A::taunt()'”

是什么导致上述代码中的错误消息?我错过了什么吗?

更新:

#include <iostream>
using namespace std;

class B
{
public:
  int getMsg(int i)
  {
    return i + 1;
  }
};

class A
{
  B b;
public:
  void run()
  {
    taunt(b.getMsg);
  }

  void taunt(int (B::*msg)(int))
  {
    cout << (*msg)(1) << endl;
  }
};

int main()
{
  A a;
  a.run();
}

t.cpp:在成员函数“void A::run()”中:第 19 行:错误:没有匹配函数调用“A::taunt()”编译由于 -Wfatal 错误而终止。

将 (*msg)(int) 更改为 (B::*msg)(int) 后,我仍然遇到相同的错误

4

3 回答 3

2

b.getMsg不是形成指向成员的指针的正确方法,您需要&B::getMsg.

(*msg)(1)不是通过指向成员的指针调用函数的正确方法,您需要指定一个对象来调用该函数,例如(使用临时)(B().*msg)(1)

于 2012-05-04T19:15:04.120 回答
0

在 OOP 中做这些事情的正确方法是使用接口,所以您需要做的就是定义一个接口并在 B 类中实现它,然后将实现此接口的实例的指针传递给 A 类中的方法。

class IB{
public:
 virtual void doSomething()=0;
};

class B: public IB{
public:
 virtual void doSomething(){...}
};

class A{
public:
 void doSomethingWithB(IB* b){b->doSomething();}
};
于 2012-05-04T19:18:43.117 回答
0

这适用于 VS 2010。所有行的输出都相同:

#include <iostream>
#include <memory>
#include <functional>

using namespace std;
using namespace std::placeholders;

class A
{
public:
    int foo(int a, float b)
    {
        return int(a*b);
    }
};

int main(int argc, char* argv[])
{
    A temp;

    int x = 5;
    float y = 3.5;

    auto a = std::mem_fn(&A::foo);
    cout << a(&temp, x, y) << endl;

    auto b = std::bind(a, &temp, x, y);
    cout << b() << endl;

    auto c = std::bind(std::mem_fn(&A::foo), &temp, _1, y);
    cout << c(5) << endl;
}

基本上,您使用std::mem_fn获取成员函数的可调用对象,然后std::bind如果要绑定其他参数,包括对象指针本身。std::ref如果您愿意的话,我很确定也有一种方法可以用来封装对对象的引用。我还包括了_1转发标记,只是为了在绑定中指定一些参数,而不是其他参数。如果您希望对所有内容都使用相同的参数但让它在不同的对象上工作,您甚至可以指定除类实例之外的所有内容。由你决定。

如果您更愿意使用boost::bind它来识别成员函数,并且您可以将它们全部放在一行上以缩短一点:auto e = boost::bind(&A::foo, &temp, x, y)但显然完全使用 std C++11 调用也没什么用。

于 2012-05-04T20:13:14.280 回答