C++中成员函数的函数指针

6

我需要调用一个期望函数指针的方法,但我想传递给它的实际上是一个函数对象。以下是我尝试做的示例:

#include <iostream>
#include "boost/function.hpp"

typedef int (*myAdder)(int);

int adderFunction(int y) { return(2 + y); }

class adderClass {
  public:
    adderClass(int x) : _x(x) {}  
    int operator() (int y) { return(_x + y); }

  private:
    int _x;
};

void printer(myAdder h, int y) {
  std::cout << h(y) << std::endl;
}

int main() {
  myAdder f = adderFunction;

  adderClass *ac = new adderClass(2);
  boost::function1<int, int> g =
    std::bind1st(std::mem_fun(&adderClass::operator()), ac);

  std::cout << f(1) << std::endl;
  std::cout << g(2) << std::endl;
  printer(f, 3);
  printer(g, 4); // Is there a way to get this to work?
}

我一直找不到一个让最后一行代码 printer(g, 4) 能够编译的方法。有没有办法让它正常工作?我能够控制的只有方法“main”和类“adderClass”。

3个回答

2
好的,这是另一次尝试:

好的,这是另一次尝试:

class CallProxy
{
public:
    static adderClass* m_instance;
    static int adder(int y)
    {
        return (*m_instance)(y);
    }
};

adderClass* CallProxy::m_instance = NULL;


int main() {
    myAdder f = adderFunction;

    adderClass ac(2);

    std::cout << f(1) << std::endl;
    std::cout << ac(2) << std::endl;
    printer(f, 3);
    CallProxy::m_instance = &ac;
    printer(CallProxy::adder, 4); 
}

问题在于您将 printer 编译为必须接收一个函数指针,没有其他选项,因此您必须发送一个函数指针。使用函数指针时,您没有人来持有您的实例。因此,此解决方案通过使用静态数据成员来解决该问题。
请注意,这使得此代码不具备线程安全性。同时执行 main 的两个线程可能会将两个不同的内容放入 m_instance 中。

1
它也不是可重入的:如果 printer 调用 main,那就麻烦了。但我认为在这些限制下,它是最好的选择,至少是可移植的。对于非可移植的解决方案,例如可以动态生成代码。 - Steve Jessop
@Steve Jessop:任何调用main()的东西都会导致未定义的行为(§3.6.1/2:“函数main不得在程序内使用(3.2)。”) - Jerry Coffin
@Jerry Coffin - 请试着超越这个愚蠢的例子所限制的范围。 - shoosh

0

像这样:

template<typename AdderT>
void printer(AdderT h, int y) {
  std::cout << h(y) << std::endl;
}

另外,你不需要使用boost::function。你可以直接这样做:

  adderClass ac(2);
  std::cout << f(1) << std::endl;
  std::cout << ac(2) << std::endl;
  printer(f, 3);
  printer(ac, 4);

可以这样做,但是(我忘了提到),方法“printer”在我无法更改的代码中。 - JamieC
我所控制的只有方法“main”和类“adderClass”。 - JamieC

0

虽然boost函数的行为类似于普通函数指针,但它是不同的类型。因此,您不能将boost函数直接赋值给函数指针。

在您的代码中,您可以简单地替换

typedef int (*myAdder)(int);

使用

typedef boost::function1< int, int > myAdder;

然后一切都会正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接