I am trying to initialize an std::array of function pointers. These pointers point to member functions of an already instantiated object.
Can somebody please help with the following example? Many thanks in advance!
#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() {}
compiling produces:
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}}};
I am using g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0.
Pointers to free functions are handled differently than pointers to member functions. The TVoidVoid type is a pointer to a free function, but you need a pointer to a Foo member function. Hence, define Foo first,
class Foo { /* As before... */ };
then go with a type alias for the member function (Foo must be known at this point)
// Note the different syntax to the former TVoidVoid
using FooVoidVoid = void (Foo::*)();
Next, Bar must be adjusted such that its data member is of type FooVoidVoid and the constructor accepts this type as an argument (the rest of Bar can be left as it is), and finally defined the array as
std::array<Bar, 3> bar_array = {{Bar{}, Bar{&Foo::myHandler}}};
Note that &Foo::myHandler has nothing to do with any existing Foo instance. It's just a pointer to a Foo member function, and only when you invoke it, this must be brought together with a Foo object (the special operators .* and ->* are meant for this to happen, or use std::invoke once you upgrade to a C++17-enabled compiler).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With