从 std::array 个函数指针调用函数

Calling function from std::array of function pointers

我不知道如何调用 std::array 中存储的函数指针,它是 class 的成员。

namespace logic {
    class Chance {
        std::array<void(logic::Chance::*)(), 15> m_redChances;
    };
}

void logic::Chance::redChance1 {
   std::cout << "Red chance one\n";
}

logic::Chance::Chance()
{
    m_redChances[0] = &Chance::redChance1;
}

到目前为止看起来还不错,但是当我想在另一个成员函数中调用这个函数时,似乎没有任何效果。只有第一行编译,但它不调用我的函数。其余部分出现错误:

logic::Chance::anotherMemberFunction() {
    m_redChances[0];
    (*m_redChances[0]*)();
    (*logic::Chance::m_redChances[0])();
    m_redChances[0]();
    *m_redChances[0]();
    *logic::Chance::m_redChances[0]();
    *logic::Chance::m_redChances[0];
    *(*m_redChances[0])();
}

operand of "*"must be a pointer type

expression precending parentheses of apprent call must have (pointer-to-) function type

编辑#

所以我尝试使用 std::function 并且不得不稍微更改 class 设计,我想实现这样的效果

struct Foo {
    std::array<std::function<void(Foo&)>, 3> funArray;

    Foo() {     
        funArray[0] = &Foo::fun1;
        funArray[1] = &Foo::fun2;       
    }

    void fun1() {
        std::cout << "fun1\n";
    }

    void fun2() {
        std::cout << "fun2\n";
    }   

    std::function<void(Foo&)> getFunction(int i) {
        return funArray[i];
    }
};  

int main() {
    Foo foo;
    foo.getFunction(0);
    std::cin.get();
}

如您所料,这不是在调用我的函数,我再次尝试了每个组合以正确 return 这个,但无法弄清楚,这是唯一一个编译但什么都不做的组合。我如何 return 另一个函数对 std::array 中存储的函数的函数调用?有点乱,但希望你明白我的意思。

std::array<void(logic::Chance::*)(), 15> m_redChances 是指向static 成员函数 [的对象的指针数组=34=] Chance。因此,您需要在要调用指向的成员函数的对象上应用。

在声明中:

(*logic::Chance::m_redChances[0])();

未提供对象。该调用将针对哪个对象的数据执行?

考虑到 chanceChance 的对象和 chance_ptr 指向同一类型对象的指针,调用将以这种方式执行:

(chance.*m_redChances[0])();
(chance_ptr->*m_redChances[0])();

即分别使用运算符.*->*

对象需要调用一个成员函数,作为*this当前对象。您使用 .*->* 运算符通过对象调用它。例如。 (o.*mf)( args ).

Andrei 在他的《现代 C++ 编程》一书中指出的愚蠢事实:o.*mf 生成一个没有类型的可调用实体。

在 C++11 及更高版本中,您可以使用 std::function 有效地将这样的对象+函数指针对存储为可调用实体。其他一些语言直接支持它。例如,它对应于 C# delegate.


示例。

#include <array>
#include <iostream>
using namespace std;

struct Foo
{
    void blah() { cout << "Blah!" << endl; }
};

auto main()
    -> int
{
    array<void (Foo::*)(), 3> mf = {nullptr, nullptr, &Foo::blah};

    Foo o;
    Foo* o_ptr = &o;

    (o_ptr->*mf[2])();
}

在您的 std::function 示例中,您可以简单地更改

foo.getFunction(0);

改为说

foo.getFunction(0)(foo);

这与其他答案中提到的相同原因有关,指向成员函数的指针本身并不链接到对象。它需要 this 才能继续工作。

如果您想将 std::function 绑定到特定对象,您可以使用 lambda 来做到这一点,就像这样。

#include <iostream>
#include <array>
#include <functional>

struct Foo {
    std::array<std::function<void()>, 3> funArray; // Notice the change in signature to void()

    Foo() {     
        funArray[0] = [&](){ fun1(); }; // Here & is catching this by reference and this lambda will always call fun1 on the current object.
        funArray[1] = [&](){ fun2(); };
    }

    void fun1() {
        std::cout << "fun1\n";
    }

    void fun2() {
        std::cout << "fun2\n";
    }   

    std::function<void()> getFunction(int i) {
        return funArray[i];
    }
};  

int main() {
    Foo foo;
    foo.getFunction(0)(); // We get a function returned, so we need to call if by adding one more () at the end


    auto storedFunction = foo.getFunction(1); // We can also store it
    storedFunction(); // and call it later
}