我无法弄清楚如何调用存储在作为类成员的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
中函数调用的函数调用?有点乱,但希望你明白我的意思。
答案 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
}