使用constexpr对象的函数指针成员函数初始化std :: array

时间:2019-03-13 08:55:42

标签: c++ c++14

我正在尝试初始化函数指针的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

1 个答案:

答案 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