从 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])();
未提供对象。该调用将针对哪个对象的数据执行?
考虑到 chance
是 Chance
的对象和 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
}
我不知道如何调用 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])();
未提供对象。该调用将针对哪个对象的数据执行?
考虑到 chance
是 Chance
的对象和 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
}