【问题标题】:Passing any generic function as a C++ argument [duplicate]将任何通用函数作为 C++ 参数传递[重复]
【发布时间】:2014-10-27 20:31:07
【问题描述】:

我正在尝试将任何通用函数作为参数传递给 C++ 函数。作为一个额外的乐趣,该函数将驻留在它自己的单独类中。在这种特殊情况下,它们都将不接受任何参数并返回void。这包括任何泛型类的成员。

我当前的代码如下:

class functionsFedHere {
public:
    void (*callback)();
    functionsFedHere(void(*)());
}

functionsFedHere::functionsFedHere (void(*callbackFunction)()) {
    callback = callbackFunction;
}

void fn1() { cout<<"Fn1"<<endl; }

class myClass {
public:
    int i;
    void fn2() { cout<<i<<endl; }
}

class myOtherClass {
public:
    string j;
    void fn3() { cout<<j<<endl; }
}

int main() {

    // Initialise some objects
    myClass b;
    b.i = 2;

    myOtherClass c;
    c.j = "some text";

    // Works fine with non-member functions
    functionsFedHere objectA(fn1);
    objectA.callback();

    // Doesn't work with member functions
    functionsFedHere objectB(b.fn2);
    functionsFedHere objectC(c.fn3);
}

我见过a forwarding function 或boost::bind 之类的解决方案,但据我所知,我认为这些解决方案不适合?

还值得注意的是,最终我想通过指针数组来传递成员函数。例如,如果myPointer[] 是一个指向myClass 类对象的指针数组,那么能够编写如下内容会很不错:

functionsFedHere objectD(myPointer[0]->fn2);

编辑:显然我不够清楚。 This answer 不是一个合适的答案,因为我希望将成员函数和非成员函数都作为参数传递(而建议的答案是设置一个指向同一类成员的函数的成员指针)。

我不认为转发函数的例子会起作用,因为转发函数假设一个单一的类类型,我想传递一个泛型类的对象。

boost::bind 很可能是答案;我只是对它不熟悉。谁能指点我一些适合新手的阅读材料?

EDIT 2:抱歉,忘了说我在pre-C++11的设备上编程。

【问题讨论】:

  • “我认为这些解决方案不适合?” 为什么??
  • boost::bind 是解决方案,除非您可以将函数 myClass::fn2 和 myOtherClass::fn3 定义为静态。
  • @πάνταῥεῖ 原始帖子已被编辑以阐明为什么建议的解决方案不是答案。
  • @Alec 我想说您可以将boost 解决方案同样用于C++ 11 之前的编译器。否则,您需要按照此处答案中的建议来酿造自己的东西。 myPointer[0]-&gt;fn2 根本不会产生成员函数指针,而且永远不会,句号!这就是副本中详细解释的内容。

标签: c++ function pointers arguments member


【解决方案1】:

使用std::function:

class functionsFedHere {
public:
    typedef std::function<void()> Func;
    Func callback;
    functionsFedHere(Func callback_) : callback(callback_) {}
};

void fn1() { cout<<"Fn1"<<endl; }

class myClass {
public:
    int i;
    void fn2() { cout<<i<<endl; }
};

class myOtherClass {
public:
    string j;
    void fn3() { cout<<j<<endl; }
};

class callableClass {
public:
    void operator()() { std::cout << "in callableClass" << std::endl; }
};

int main() {

    // Initialise some objects
    myClass b;
    b.i = 2;

    myOtherClass c;
    c.j = "some text";

    // Works fine with non-member functions
    functionsFedHere objectA(fn1);
    objectA.callback();

    // Works with member functions now
    functionsFedHere objectB(std::bind(&myClass::fn2, b));
    objectB.callback();
    functionsFedHere objectC(std::bind(&myOtherClass::fn3, c));
    objectC.callback();

    // Works with lambdas as well
    functionsFedHere objectLambda([]() { std::cout << "in lambda" << std::endl; });
    objectLambda.callback();

    // Works also with classes with overloaded operator()
    functionsFedHere(callableClass()).callback();
    return 0;
}

【讨论】:

  • 通过其中一个成员函数展示 lambdas 的使用,您将获得我的支持。
  • @AntonSavin 这看起来是个不错的解决方案,但我忘了说我是 C++11 之前的版本。
  • @Alec 在这种情况下,您可以将boost::function 与boost::bind 一起使用——本质上是相同的。
猜你喜欢
  • 2011-04-07
  • 2021-04-24
  • 2022-01-16
  • 2013-08-13
  • 2017-02-12
  • 2023-03-03
  • 2019-07-23
  • 2015-09-28
相关资源
最近更新 更多