Reputation: 1897
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
.
Upvotes: 3
Views: 122
Reputation: 38315
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).
Upvotes: 3