Инициализация std :: array с помощью функции-указателя на функцию-член объекта constexpr - PullRequest
3 голосов
/ 13 марта 2019

Я пытаюсь инициализировать массив указателей на функции std ::.Эти указатели указывают на функции-члены уже созданного объекта.

Может кто-нибудь помочь с приведенным ниже примером?Заранее большое спасибо!

#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 Ответ

3 голосов
/ 13 марта 2019

Указатели на свободные функции обрабатываются иначе, чем указатели на функции-члены.Тип 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 (специальные операторы .* и ->* предназначены для этого или используютstd::invoke после обновления до компилятора с поддержкой C ++ 17.

...