【问题标题】:C++ : unresolved overloaded function when using function pointersC ++:使用函数指针时未解析的重载函数
【发布时间】:2012-05-04 19:01:14
【问题描述】:
#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...上面的代码生成了以下错误消息:“error: no matching function for call to '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) 后,我仍然遇到同样的错误

【问题讨论】:

  • 你不能像在 C++ 中那样使用成员函数指针。试着用谷歌搜索一下,那里有很多关于它的文章。
  • 在一个地方你传递了一个int,而在另一个地方,你传递了一个int(B::*)(int),而在另一个地方,你传递了一个int(*)(int);你为什么期望这行得通?
  • 我刚刚注意到...并且我刚刚修复了它

标签: c++ function-pointers


【解决方案1】:

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

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

【讨论】:

  • @SethCarnegie:&amp; 是必需的。 ISO/IEC 14882:2011 5.3.1 / 4:“仅当使用显式 &amp; 并且其操作数是未括在括号中的 qualified-id 时,才会形成指向成员的指针。”
  • 啊,你说的很对,谢谢指正。如果可以的话,我会再次为你 +1 :)
【解决方案2】:

在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();}
};

【讨论】:

    【解决方案3】:

    这适用于 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(&amp;A::foo, &amp;temp, x, y) 但显然完全使用标准 C++ 并没有更多11个电话。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多