#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-errors而导致编译终止。
将(* msg)(int)更改为(B :: * msg)(int)之后我仍然得到相同的错误
答案 0 :(得分:2)
b.getMsg
不是形成指向成员的指针的正确方法,您需要&B::getMsg
。
(*msg)(1)
不是通过指向成员的指针调用函数的正确方法,您需要指定一个对象来调用该函数,例如: (使用临时的)(B().*msg)(1)
。
答案 1 :(得分: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();}
};
答案 2 :(得分: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调用。