如何调用作为参数给出的 C++ class 方法?

How to call a C++ class method, which is given as a parameter?

我正在尝试将一个方法作为参数传递给其他方法。

Magner.h:

Class Manager{
public:
 timeCount(void (Manger::*function)(void));
void passedFuction();
}

Manager.cpp 中,我正在尝试通过

呼叫 timeCount
timeCount(&Manager::passedFuction());

TimeCount 正文:

void Manager::timeCount(void(Manager::*function)(void))
{
    std::cout << "It works";
    (*function)(); // here is error
}

ViusalStudio 说:

void*Manager::*function)() operand of '*' must be a pointer

我该如何纠正? 我学习的例子是:http://www.cplusplus.com/forum/beginner/6596/

A​​ pointer-to-member-function (pmf) 不是指针。让我重复一遍:

A pointer-to-member-function 不是 指针。

要调用 pmf,您必须为其提供要调用它的对象。你可能想要:

    (this->*function)();

如果您有另一个正确类型的对象 obj,您还可以使用:

    (obj.*function)();

void (Manger::*function)(void) 语法用于 Manager class 的成员函数,不能与 Manager 之外的函数一起使用] class.

要修复此缺点,请改为传递 std::function<void(void)>,这样您就可以使用常规函数调用语法调用自身:

void Manager::timeCount(std::function<void(void)> f) {
    std::cout << "It works";
    f();
}

这里是如何调用 timeCount 成员和 non-member 函数的完整演示:

struct Manager {
    string name;
    void timeCount(std::function<void(void)> f) {
        std::cout << "This is " << name << " manager" << endl;
        f();
    }
};

void foo() {
    cout << "I'm foo" << endl;
}

struct Test {
    int x;
    void bar() {
        cout << "I'm bar " << x << endl;
    }
};

int main() {
    Manager mgr {"time"};
    mgr.timeCount(foo);
    Test tst = {234};
    mgr.timeCount(std::bind( &Test::bar, tst));
    return 0;
}

Demo.

从 c++17 开始,我们有 std::invoke:

std::invoke(function, this);

std::invoke(function, *this);

都可以。最小演示:

#include <functional>
#include <iostream>
class Manager
{
public:
    void timeCount(void (Manager::*function)(void));
    void passedFuction()
    {
        std::cout << "call passedFunction\n";
    }
};

void Manager::timeCount(void (Manager::*function)(void))
{
    std::cout << "It works\n";
    std::invoke(function, *this);
    //    (*function)(); // here is error
}

int main()
{
    Manager a;
    a.timeCount(&Manager::passedFuction);
}

It works

call passedFunction

live demo