我正在尝试初始化函数指针的std :: array。这些指针指向已经实例化的对象的成员函数。
有人可以帮助以下示例吗?提前非常感谢!
#include <array>
using TVoidVoid = void (*)(void);
class Foo {
public:
constexpr Foo() {}
void myHandler() {}
};
class Bar {
public:
constexpr Bar() : handler_{nullptr} {}
constexpr Bar(TVoidVoid handler) : handler_{handler} {}
private:
TVoidVoid handler_;
};
Foo f;
std::array<Bar, 5> bar_array = {{Bar{}, Bar{f.myHandler}}};
int main() {}
编译产生:
main.cpp:22:56: error: no matching function for call to ‘Bar::Bar(<brace-enclosed initializer list>)’
std::array<Bar, 5> bar_array = {{Bar{}, Bar{f.myHandler}}};
我正在使用g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
。
答案 0 :(得分:3)
指向自由函数的指针与指向成员函数的指针的处理方式不同。 TVoidVoid
类型是指向自由函数的指针,但是您需要指向Foo
成员函数的指针。因此,请首先定义Foo
,
class Foo { /* As before... */ };
然后带有成员函数的类型别名(此时必须知道Foo
)
// Note the different syntax to the former TVoidVoid
using FooVoidVoid = void (Foo::*)();
接下来,必须对Bar
进行调整,使其数据成员的类型为FooVoidVoid
,并且构造函数接受此类型作为参数(Bar
的其余部分可以保留为原样) ),最后将数组定义为
std::array<Bar, 3> bar_array = {{Bar{}, Bar{&Foo::myHandler}}};
请注意,&Foo::myHandler
与任何现有的Foo
实例无关。它只是指向Foo
成员函数的指针,只有在调用它时,它才必须与Foo
对象一起(特殊操作符.*
和->*
就是要做到这一点,或者在升级到支持C ++ 17的编译器后使用std::invoke
。