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

时间:2018-01-20 09:02:29

标签: c++ arrays std function-pointers

我无法弄清楚如何调用存储在作为类成员的std::array中的函数指针。

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

“*”的操作数必须是指针类型

  

表达式必须具有apprent调用的括号之前的表达式   (指向)函数类型

EDIT#

所以我尝试使用std::function并且不得不改变一下类设计,我想实现类似的东西

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

你可以猜到,这不是调用我的函数而是我再一次尝试每一个组合来正确地返回它,但是无法弄明白,那是唯一一个编译,但什么都不做的。如何通过另一个函数返回std::array中函数调用的函数调用?有点乱,但希望你明白我的意思。

3 个答案:

答案 0 :(得分:3)

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

声明中:

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

没有提供任何对象。哪个对象的数据是要执行的调用?

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

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

也就是说,分别使用运算符.*->*

答案 1 :(得分:1)

需要在对象上调用成员函数,以充当*this 当前对象。您可以使用.*->*运算符来调用对象。例如。 (o.*mf)( args )

愚蠢 - 安德烈在其现代C ++编程书中指出:o.*mf生成一个没有类型的可调用实体。

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

实施例

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

答案 2 :(得分:1)

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
}