Я хочу создать массив указателей на методы, чтобы я мог быстро выбрать метод для вызова на основе целого числа. Но я немного борюсь с синтаксисом.
То, что у меня есть сейчас, это:
class Foo {
private:
void method1();
void method2();
void method3();
void(Foo::*display_functions[3])() = {
Foo::method1,
Foo::method2,
Foo::method3
};
};
Но я получаю следующее сообщение об ошибке:
[bf@localhost method]$ make test
g++ test.cpp -o test
test.cpp:11:9: error: cannot convert ‘Foo::method1’ from type ‘void (Foo::)()’ to type ‘void (Foo::*)()’
11 | };
| ^
test.cpp:11:9: error: cannot convert ‘Foo::method2’ from type ‘void (Foo::)()’ to type ‘void (Foo::*)()’
test.cpp:11:9: error: cannot convert ‘Foo::method3’ from type ‘void (Foo::)()’ to type ‘void (Foo::*)()’
make: *** [<builtin>: test] Error 1
Как насчет функции-члена, принимающей это целое число в качестве параметра и вызывающей соответствующую функцию в switch
/case
? Гораздо менее хрупкий.
Вы пробовали &Foo::method1, &Foo::method2, &Foo::method3
?
Чтобы получить указатель на функцию-член, вы всегда должны использовать оператор указателя на &
.
Часто очень трудно понять объявления C, если вы используете стандартные контейнеры, такие как std::array и std::function вместо указателей функций в стиле C, отлаживать намного проще.
Да, можно, нужно только взять адрес из них:
void(Foo::*display_functions[3])() = {
&Foo::method1,
&Foo::method2,
&Foo::method3
};
... однако, вероятно, будет лучше, если у вас есть virtual
методы для интерфейса или простой метод, который вызывает их все для шаблона с несколькими методами.
Вы можете использовать typedef
для типа указателя на ваши методы, а затем хранить свои методы в std::array, содержащем этот тип:
class Foo {
private:
void method1() {};
void method2() {};
void method3() {};
typedef void (Foo::* FooMemFn)();
std::array<FooMemFn,3> display_functions = {
&Foo::method1,
&Foo::method2,
&Foo::method3
};
};
Вместо typedef
вы также можете использовать оператор using
:
using FooMemFn = void (Foo::*)();
Обратите внимание, что вы должны использовать operator&
с методом класса, чтобы получить указатель на метод.
Дополнительное примечание: подумайте о том, чтобы сделать display_functions
статическим, если он не будет меняться между различными экземплярами класса.
Не только static
. Этот массив может быть даже constexpr
в C++20. В частности, gcc может оптимизировать вызов, если индексом является constexpr: godbolt.org/z/44o47rqqd
Вы можете создать
std::vector<std::function<...>>
.