2012-05-04 124 views
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传入嘲讽...上述代码生成以下错误消息:“错误:没有匹配函数调用'A :: taunt()'”C++:使用函数指针时的无法解析的重载函数

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

更新:

#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 ::运行()': 第19行:错误:调用没有匹配的函数 'A ::嘲讽()'由于 - 重大错误,编译终止了 。

改变(* MSG)(INT)后,我仍然得到同样的错误(B :: * MSG)(INT)

+0

不能像C++那样使用成员函数指针。尝试使用谷歌搜索,有很多关于它的文章。 – mfontanini

+0

在一个地方,你传递一个'int',期望一个'int(*)(int)',另一个你传递一个'int(B :: *)(int)',其中一个int (*)(int)'是预期的;你为什么希望这个工作? – ildjarn

+0

我刚刚注意到了......我只是修复了它 – user52343

回答

2

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

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

+1

+1,虽然你并不需要'&'。 –

+0

@SethCarnegie:'&'是必需的。 ISO/IEC 14882:2011 5.3.1/4:“只有在使用明确的&时才会形成指向成员的指针,并且其操作数是不包含在圆括号中的_qualified-id_。 –

+0

啊,你说得对,谢谢你的纠正。如果我可以的话,我会再次给你+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();} 
}; 
0

此工程于2010年VS输出是所有线路上的相同:

#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调用也不多。